]>
Commit | Line | Data |
---|---|---|
22f3fd98 | 1 | |
2 | /* | |
262a0e14 | 3 | * $Id$ |
22f3fd98 | 4 | * |
5 | * DEBUG: section 16 Cache Manager Objects | |
6 | * AUTHOR: Duane Wessels | |
7 | * | |
2b6662ba | 8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
e25c139f | 9 | * ---------------------------------------------------------- |
22f3fd98 | 10 | * |
2b6662ba | 11 | * Squid is the result of efforts by numerous individuals from |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
22f3fd98 | 19 | * |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
26ac0430 | 24 | * |
22f3fd98 | 25 | * This program is distributed in the hope that it will be useful, |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
26ac0430 | 29 | * |
22f3fd98 | 30 | * You should have received a copy of the GNU General Public License |
31 | * along with this program; if not, write to the Free Software | |
cbdec147 | 32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
e25c139f | 33 | * |
22f3fd98 | 34 | */ |
5c336a3b | 35 | #include "config.h" |
62ee09ca | 36 | #include "CacheManager.h" |
5c336a3b | 37 | #include "comm/Connection.h" |
aa839030 | 38 | #include "errorpage.h" |
528b2c61 | 39 | #include "HttpReply.h" |
40 | #include "HttpRequest.h" | |
e6ccf245 | 41 | #include "Store.h" |
528b2c61 | 42 | #include "fde.h" |
985c86bc | 43 | #include "SquidTime.h" |
d295d770 | 44 | #include "wordlist.h" |
3e1da049 | 45 | #include "Debug.h" |
22f3fd98 | 46 | |
74990ce1 AJ |
47 | // for rotate_logs() |
48 | #include "protos.h" | |
49 | ||
63be0a78 | 50 | /// \ingroup CacheManagerInternal |
22f3fd98 | 51 | #define MGR_PASSWD_SZ 128 |
52 | ||
c83f0bd5 | 53 | |
d154d3ec FC |
54 | /** |
55 | \ingroup CacheManagerInternals | |
56 | * Constructor. Its purpose is to register internal commands | |
57 | */ | |
62ee09ca | 58 | CacheManager::CacheManager() |
59 | { | |
dce760db FC |
60 | registerAction(new OfflineToggleAction); |
61 | registerAction(new ShutdownAction); | |
62 | registerAction(new ReconfigureAction); | |
0383747d | 63 | registerAction(new RotateAction); |
afea465e | 64 | registerAction(new MenuAction(this)); |
62ee09ca | 65 | } |
22f3fd98 | 66 | |
d154d3ec FC |
67 | /** |
68 | \ingroup CacheManagerAPI | |
69 | * Registers a C-style action, which is implemented as a pointer to a function | |
70 | * taking as argument a pointer to a StoreEntry and returning void. | |
71 | * Implemented via CacheManagerActionLegacy. | |
72 | */ | |
22f3fd98 | 73 | void |
62ee09ca | 74 | CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) |
22f3fd98 | 75 | { |
1d8395bd K |
76 | debugs(16, 3, "CacheManager::registerAction: registering legacy " << action); |
77 | registerAction(new CacheManagerActionLegacy(action,desc,pw_req_flag,atomic,handler)); | |
78 | } | |
62e76326 | 79 | |
d154d3ec | 80 | /** |
e0d28505 | 81 | * \ingroup CacheManagerAPI |
26ac0430 | 82 | * Registers a C++-style action, via a poiner to a subclass of |
d154d3ec FC |
83 | * a CacheManagerAction object, whose run() method will be invoked when |
84 | * CacheManager identifies that the user has requested the action. | |
85 | */ | |
1d8395bd K |
86 | void |
87 | CacheManager::registerAction(CacheManagerAction *anAction) | |
88 | { | |
89 | char *action = anAction->action; | |
62ee09ca | 90 | if (findAction(action) != NULL) { |
03c4599f | 91 | debugs(16, 2, "CacheManager::registerAction: Duplicate '" << action << "'. Skipping."); |
62e76326 | 92 | return; |
e45867bd | 93 | } |
62e76326 | 94 | |
528b2c61 | 95 | assert (strstr (" ", action) == NULL); |
62e76326 | 96 | |
afea465e | 97 | ActionsList += anAction; |
62e76326 | 98 | |
62ee09ca | 99 | debugs(16, 3, "CacheManager::registerAction: registered " << action); |
100 | } | |
101 | ||
1d8395bd | 102 | |
d154d3ec FC |
103 | /** |
104 | \ingroup CacheManagerInternal | |
105 | * Locates an action in the actions registry ActionsList. | |
106 | \retval NULL if Action not found | |
107 | \retval CacheManagerAction* if the action was found | |
108 | */ | |
62ee09ca | 109 | CacheManagerAction * |
110 | CacheManager::findAction(char const * action) | |
22f3fd98 | 111 | { |
03c4599f K |
112 | CacheManagerActionList::iterator a; |
113 | ||
114 | debugs(16, 5, "CacheManager::findAction: looking for action " << action); | |
afea465e | 115 | for ( a = ActionsList.begin(); a != ActionsList.end(); a++) { |
03c4599f K |
116 | if (0 == strcmp((*a)->action, action)) { |
117 | debugs(16, 6, " found"); | |
118 | return *a; | |
119 | } | |
22f3fd98 | 120 | } |
62e76326 | 121 | |
03c4599f | 122 | debugs(16, 6, "Action not found."); |
22f3fd98 | 123 | return NULL; |
124 | } | |
125 | ||
832c08ab FC |
126 | /** |
127 | \ingroup CacheManagerInternal | |
128 | * define whether the URL is a cache-manager URL and parse the action | |
129 | * requested by the user. Checks via CacheManager::ActionProtection() that the | |
130 | * item is accessible by the user. | |
131 | \retval CacheManager::cachemgrStateData state object for the following handling | |
132 | \retval NULL if the action can't be found or can't be accessed by the user | |
133 | */ | |
bdaaf1a1 | 134 | CacheManager::cachemgrStateData * |
c83f0bd5 | 135 | CacheManager::ParseUrl(const char *url) |
22f3fd98 | 136 | { |
137 | int t; | |
138 | LOCAL_ARRAY(char, host, MAX_URL); | |
139 | LOCAL_ARRAY(char, request, MAX_URL); | |
140 | LOCAL_ARRAY(char, password, MAX_URL); | |
62ee09ca | 141 | CacheManagerAction *a; |
22f3fd98 | 142 | cachemgrStateData *mgr = NULL; |
7395afb8 | 143 | const char *prot; |
22f3fd98 | 144 | t = sscanf(url, "cache_object://%[^/]/%[^@]@%s", host, request, password); |
62e76326 | 145 | |
22f3fd98 | 146 | if (t < 2) { |
62e76326 | 147 | xstrncpy(request, "menu", MAX_URL); |
cd377065 | 148 | #ifdef _SQUID_OS2_ |
62e76326 | 149 | /* |
150 | * emx's sscanf insists of returning 2 because it sets request | |
151 | * to null | |
152 | */ | |
cd377065 | 153 | } else if (request[0] == '\0') { |
62e76326 | 154 | xstrncpy(request, "menu", MAX_URL); |
cd377065 | 155 | #endif |
62e76326 | 156 | |
c83f0bd5 | 157 | } else if ((a = findAction(request)) == NULL) { |
3e1da049 | 158 | debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' not found"); |
62e76326 | 159 | return NULL; |
7395afb8 | 160 | } else { |
c83f0bd5 | 161 | prot = ActionProtection(a); |
62e76326 | 162 | |
163 | if (!strcmp(prot, "disabled") || !strcmp(prot, "hidden")) { | |
3e1da049 | 164 | debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' is " << prot); |
62e76326 | 165 | return NULL; |
166 | } | |
22f3fd98 | 167 | } |
62e76326 | 168 | |
63259c34 | 169 | /* set absent entries to NULL so we can test if they are present later */ |
e6ccf245 | 170 | mgr = (cachemgrStateData *)xcalloc(1, sizeof(cachemgrStateData)); |
62e76326 | 171 | |
63259c34 | 172 | mgr->user_name = NULL; |
62e76326 | 173 | |
63259c34 | 174 | mgr->passwd = t == 3 ? xstrdup(password) : NULL; |
62e76326 | 175 | |
22f3fd98 | 176 | mgr->action = xstrdup(request); |
62e76326 | 177 | |
22f3fd98 | 178 | return mgr; |
179 | } | |
180 | ||
63be0a78 | 181 | /// \ingroup CacheManagerInternal |
832c08ab FC |
182 | /* |
183 | \ingroup CacheManagerInternal | |
184 | * Decodes the headers needed to perform user authentication and fills | |
185 | * the details into the cachemgrStateData argument | |
186 | */ | |
c83f0bd5 K |
187 | void |
188 | CacheManager::ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request) | |
63259c34 | 189 | { |
2ac76861 | 190 | const char *basic_cookie; /* base 64 _decoded_ user:passwd pair */ |
63259c34 | 191 | const char *passwd_del; |
192 | assert(mgr && request); | |
a9925b40 | 193 | basic_cookie = request->header.getAuth(HDR_AUTHORIZATION, "Basic"); |
62e76326 | 194 | |
99edd1c3 | 195 | if (!basic_cookie) |
62e76326 | 196 | return; |
197 | ||
63259c34 | 198 | if (!(passwd_del = strchr(basic_cookie, ':'))) { |
3e1da049 | 199 | debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'"); |
62e76326 | 200 | return; |
63259c34 | 201 | } |
62e76326 | 202 | |
63259c34 | 203 | /* found user:password pair, reset old values */ |
204 | safe_free(mgr->user_name); | |
62e76326 | 205 | |
63259c34 | 206 | safe_free(mgr->passwd); |
62e76326 | 207 | |
2ac76861 | 208 | mgr->user_name = xstrdup(basic_cookie); |
62e76326 | 209 | |
63259c34 | 210 | mgr->user_name[passwd_del - basic_cookie] = '\0'; |
62e76326 | 211 | |
2ac76861 | 212 | mgr->passwd = xstrdup(passwd_del + 1); |
62e76326 | 213 | |
63259c34 | 214 | /* warning: this prints decoded password which maybe not what you want to do @?@ @?@ */ |
c83f0bd5 | 215 | debugs(16, 9, "CacheManager::ParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'"); |
63259c34 | 216 | } |
217 | ||
63be0a78 | 218 | /** |
219 | \ingroup CacheManagerInternal | |
220 | * | |
221 | \retval 0 if mgr->password is good or "none" | |
222 | \retval 1 if mgr->password is "disable" | |
223 | \retval !0 if mgr->password does not match configured password | |
22f3fd98 | 224 | */ |
c83f0bd5 K |
225 | int |
226 | CacheManager::CheckPassword(cachemgrStateData * mgr) | |
22f3fd98 | 227 | { |
c83f0bd5 K |
228 | char *pwd = PasswdGet(Config.passwd_list, mgr->action); |
229 | CacheManagerAction *a = findAction(mgr->action); | |
03c4599f K |
230 | |
231 | debugs(16, 4, "CacheManager::CheckPassword for action " << mgr->action); | |
22f3fd98 | 232 | assert(a != NULL); |
62e76326 | 233 | |
22f3fd98 | 234 | if (pwd == NULL) |
62e76326 | 235 | return a->flags.pw_req; |
236 | ||
22f3fd98 | 237 | if (strcmp(pwd, "disable") == 0) |
62e76326 | 238 | return 1; |
239 | ||
22f3fd98 | 240 | if (strcmp(pwd, "none") == 0) |
62e76326 | 241 | return 0; |
242 | ||
63259c34 | 243 | if (!mgr->passwd) |
62e76326 | 244 | return 1; |
245 | ||
22f3fd98 | 246 | return strcmp(pwd, mgr->passwd); |
247 | } | |
248 | ||
63be0a78 | 249 | /// \ingroup CacheManagerInternal |
c83f0bd5 K |
250 | void |
251 | CacheManager::StateFree(cachemgrStateData * mgr) | |
22f3fd98 | 252 | { |
2ac76861 | 253 | safe_free(mgr->action); |
254 | safe_free(mgr->user_name); | |
255 | safe_free(mgr->passwd); | |
97b5e68f | 256 | mgr->entry->unlock(); |
2ac76861 | 257 | xfree(mgr); |
22f3fd98 | 258 | } |
259 | ||
832c08ab FC |
260 | /** |
261 | \ingroup CacheManagerAPI | |
262 | * Main entry point in the Cache Manager's activity. Gets called as part | |
263 | * of the forward chain if the right URL is detected there. Initiates | |
264 | * all needed internal work and renders the response. | |
265 | */ | |
22f3fd98 | 266 | void |
5c336a3b | 267 | CacheManager::Start(const Comm::ConnectionPointer &client, HttpRequest * request, StoreEntry * entry) |
22f3fd98 | 268 | { |
269 | cachemgrStateData *mgr = NULL; | |
270 | ErrorState *err = NULL; | |
62ee09ca | 271 | CacheManagerAction *a; |
832c08ab | 272 | debugs(16, 3, "CacheManager::Start: '" << entry->url() << "'" ); |
62e76326 | 273 | |
c83f0bd5 | 274 | if ((mgr = ParseUrl(entry->url())) == NULL) { |
2cc81f1f | 275 | err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND, request); |
3900307b | 276 | err->url = xstrdup(entry->url()); |
62e76326 | 277 | errorAppendEntry(entry, err); |
278 | entry->expires = squid_curtime; | |
279 | return; | |
22f3fd98 | 280 | } |
62e76326 | 281 | |
22f3fd98 | 282 | mgr->entry = entry; |
34266cde | 283 | |
3d0ac046 | 284 | entry->lock(); |
22f3fd98 | 285 | entry->expires = squid_curtime; |
34266cde | 286 | |
5c336a3b | 287 | debugs(16, 5, "CacheManager: " << client << " requesting '" << mgr->action << "'"); |
34266cde | 288 | |
63259c34 | 289 | /* get additional info from request headers */ |
c83f0bd5 | 290 | ParseHeaders(mgr, request); |
34266cde | 291 | |
22f3fd98 | 292 | /* Check password */ |
62e76326 | 293 | |
c83f0bd5 | 294 | if (CheckPassword(mgr) != 0) { |
62e76326 | 295 | /* build error message */ |
076df709 | 296 | ErrorState *errState; |
62e76326 | 297 | HttpReply *rep; |
076df709 | 298 | errState = errorCon(ERR_CACHE_MGR_ACCESS_DENIED, HTTP_UNAUTHORIZED, request); |
62e76326 | 299 | /* warn if user specified incorrect password */ |
300 | ||
301 | if (mgr->passwd) | |
26ac0430 AJ |
302 | debugs(16, DBG_IMPORTANT, "CacheManager: " << |
303 | (mgr->user_name ? mgr->user_name : "<unknown>") << "@" << | |
5c336a3b | 304 | client << ": incorrect password for '" << |
bf8fe701 | 305 | mgr->action << "'" ); |
62e76326 | 306 | else |
26ac0430 AJ |
307 | debugs(16, DBG_IMPORTANT, "CacheManager: " << |
308 | (mgr->user_name ? mgr->user_name : "<unknown>") << "@" << | |
5c336a3b AJ |
309 | client << ": password needed for '" << |
310 | mgr->action << "'"); | |
62e76326 | 311 | |
076df709 | 312 | rep = errState->BuildHttpReply(); |
62e76326 | 313 | |
076df709 | 314 | errorStateFree(errState); |
62e76326 | 315 | |
316 | /* | |
317 | * add Authenticate header, use 'action' as a realm because | |
318 | * password depends on action | |
319 | */ | |
a9925b40 | 320 | rep->header.putAuth("Basic", mgr->action); |
62e76326 | 321 | |
322 | /* store the reply */ | |
db237875 | 323 | entry->replaceHttpReply(rep); |
62e76326 | 324 | |
325 | entry->expires = squid_curtime; | |
326 | ||
327 | entry->complete(); | |
328 | ||
c83f0bd5 | 329 | StateFree(mgr); |
62e76326 | 330 | |
331 | return; | |
22f3fd98 | 332 | } |
62e76326 | 333 | |
0be039f4 | 334 | debugs(16, 2, "CacheManager: " << |
26ac0430 | 335 | (mgr->user_name ? mgr->user_name : "<unknown>") << "@" << |
5c336a3b | 336 | client << " requesting '" << |
bf8fe701 | 337 | mgr->action << "'" ); |
22f3fd98 | 338 | /* retrieve object requested */ |
c83f0bd5 | 339 | a = findAction(mgr->action); |
22f3fd98 | 340 | assert(a != NULL); |
62e76326 | 341 | |
3900307b | 342 | entry->buffer(); |
62e76326 | 343 | |
cb69b4c7 | 344 | { |
06a5ae20 | 345 | HttpReply *rep = new HttpReply; |
11992b6f | 346 | rep->setHeaders(HTTP_OK, NULL, "text/plain", -1, squid_curtime, squid_curtime); |
db237875 | 347 | entry->replaceHttpReply(rep); |
cb69b4c7 | 348 | } |
62e76326 | 349 | |
c83f0bd5 | 350 | a->run(entry); |
62e76326 | 351 | |
3900307b | 352 | entry->flush(); |
b66315e4 | 353 | |
354 | if (a->flags.atomic) | |
62e76326 | 355 | entry->complete(); |
62e76326 | 356 | |
c83f0bd5 | 357 | StateFree(mgr); |
22f3fd98 | 358 | } |
359 | ||
832c08ab | 360 | /// \ingroup CacheManagerInternal |
dce760db | 361 | void CacheManager::ShutdownAction::run(StoreEntry *sentry) |
22f3fd98 | 362 | { |
3e1da049 | 363 | debugs(16, DBG_CRITICAL, "Shutdown by Cache Manager command."); |
22f3fd98 | 364 | shut_down(0); |
365 | } | |
832c08ab | 366 | /// \ingroup CacheManagerInternal |
dce760db | 367 | CacheManager::ShutdownAction::ShutdownAction() : CacheManagerAction("shutdown","Shut Down the Squid Process", 1, 1) { } |
22f3fd98 | 368 | |
832c08ab | 369 | /// \ingroup CacheManagerInternal |
c83f0bd5 | 370 | void |
dce760db | 371 | CacheManager::ReconfigureAction::run(StoreEntry * sentry) |
757a2291 | 372 | { |
e680134c | 373 | debugs(16, DBG_IMPORTANT, "Reconfigure by Cache Manager command."); |
757a2291 GS |
374 | storeAppendPrintf(sentry, "Reconfiguring Squid Process ...."); |
375 | reconfigure(SIGHUP); | |
376 | } | |
832c08ab | 377 | /// \ingroup CacheManagerInternal |
dce760db | 378 | CacheManager::ReconfigureAction::ReconfigureAction() : CacheManagerAction("reconfigure","Reconfigure Squid", 1, 1) { } |
757a2291 | 379 | |
0383747d AJ |
380 | /// \ingroup CacheManagerInternal |
381 | void | |
382 | CacheManager::RotateAction::run(StoreEntry * sentry) | |
383 | { | |
384 | debugs(16, DBG_IMPORTANT, "Rotate Logs by Cache Manager command."); | |
385 | storeAppendPrintf(sentry, "Rotating Squid Process Logs ...."); | |
386 | #ifdef _SQUID_LINUX_THREADS_ | |
387 | rotate_logs(SIGQUIT); | |
388 | #else | |
389 | rotate_logs(SIGUSR1); | |
390 | #endif | |
391 | } | |
392 | /// \ingroup CacheManagerInternal | |
393 | CacheManager::RotateAction::RotateAction() : CacheManagerAction("rotate","Rotate Squid Logs", 1, 1) { } | |
394 | ||
63be0a78 | 395 | /// \ingroup CacheManagerInternal |
c83f0bd5 | 396 | void |
dce760db | 397 | CacheManager::OfflineToggleAction::run(StoreEntry * sentry) |
d20b1cd0 | 398 | { |
399 | Config.onoff.offline = !Config.onoff.offline; | |
3e1da049 | 400 | debugs(16, DBG_IMPORTANT, "offline_mode now " << (Config.onoff.offline ? "ON" : "OFF") << " by Cache Manager request."); |
bf8fe701 | 401 | |
d20b1cd0 | 402 | storeAppendPrintf(sentry, "offline_mode is now %s\n", |
62e76326 | 403 | Config.onoff.offline ? "ON" : "OFF"); |
d20b1cd0 | 404 | } |
832c08ab | 405 | /// \ingroup CacheManagerInternal |
dce760db | 406 | CacheManager::OfflineToggleAction::OfflineToggleAction() : CacheManagerAction ("offline_toggle", "Toggle offline_mode setting", 1, 1) { } |
d20b1cd0 | 407 | |
832c08ab FC |
408 | /* |
409 | \ingroup CacheManagerInternal | |
410 | * Renders the protection level text for an action. | |
411 | * Also doubles as a check for the protection level. | |
832c08ab | 412 | */ |
c83f0bd5 K |
413 | const char * |
414 | CacheManager::ActionProtection(const CacheManagerAction * at) | |
7395afb8 | 415 | { |
416 | char *pwd; | |
417 | assert(at); | |
c83f0bd5 | 418 | pwd = PasswdGet(Config.passwd_list, at->action); |
62e76326 | 419 | |
7395afb8 | 420 | if (!pwd) |
62e76326 | 421 | return at->flags.pw_req ? "hidden" : "public"; |
422 | ||
7395afb8 | 423 | if (!strcmp(pwd, "disable")) |
62e76326 | 424 | return "disabled"; |
425 | ||
7395afb8 | 426 | if (strcmp(pwd, "none") == 0) |
62e76326 | 427 | return "public"; |
428 | ||
7395afb8 | 429 | return "protected"; |
430 | } | |
431 | ||
63be0a78 | 432 | /// \ingroup CacheManagerInternal |
c83f0bd5 | 433 | void |
bdaaf1a1 | 434 | CacheManager::MenuAction::run(StoreEntry * sentry) |
22f3fd98 | 435 | { |
03c4599f | 436 | CacheManagerActionList::iterator a; |
62e76326 | 437 | |
03c4599f | 438 | debugs(16, 4, "CacheManager::MenuCommand invoked"); |
afea465e | 439 | for (a = cmgr->ActionsList.begin(); a != cmgr->ActionsList.end(); ++a) { |
03c4599f | 440 | debugs(16, 5, " showing action " << (*a)->action); |
e1a88700 | 441 | storeAppendPrintf(sentry, " %-22s\t%-32s\t%s\n", |
26ac0430 | 442 | (*a)->action, (*a)->desc, cmgr->ActionProtection(*a)); |
7395afb8 | 443 | } |
22f3fd98 | 444 | } |
832c08ab | 445 | /// \ingroup CacheManagerInternal |
e5d1c7ec | 446 | CacheManager::MenuAction::MenuAction(CacheManager *aMgr) : CacheManagerAction ("menu", "Cache Manager Menu", 0, 1), cmgr(aMgr) { } |
22f3fd98 | 447 | |
832c08ab FC |
448 | /* |
449 | \ingroup CacheManagerInternal | |
450 | * gets from the global Config the password the user would need to supply | |
451 | * for the action she queried | |
452 | */ | |
c83f0bd5 K |
453 | char * |
454 | CacheManager::PasswdGet(cachemgr_passwd * a, const char *action) | |
22f3fd98 | 455 | { |
456 | wordlist *w; | |
62e76326 | 457 | |
22f3fd98 | 458 | while (a != NULL) { |
62e76326 | 459 | for (w = a->actions; w != NULL; w = w->next) { |
460 | if (0 == strcmp(w->key, action)) | |
461 | return a->passwd; | |
462 | ||
463 | if (0 == strcmp(w->key, "all")) | |
464 | return a->passwd; | |
465 | } | |
466 | ||
467 | a = a->next; | |
22f3fd98 | 468 | } |
62e76326 | 469 | |
22f3fd98 | 470 | return NULL; |
471 | } | |
c83f0bd5 K |
472 | |
473 | CacheManager* CacheManager::instance=0; | |
474 | ||
832c08ab FC |
475 | /** |
476 | \ingroup CacheManagerAPI | |
477 | * Singleton accessor method. | |
478 | */ | |
c83f0bd5 | 479 | CacheManager* |
26ac0430 AJ |
480 | CacheManager::GetInstance() |
481 | { | |
482 | if (instance == 0) { | |
483 | debugs(16, 6, "CacheManager::GetInstance: starting cachemanager up"); | |
484 | instance = new CacheManager; | |
485 | } | |
486 | return instance; | |
c83f0bd5 K |
487 | } |
488 | ||
489 | ||
832c08ab | 490 | /// \ingroup CacheManagerInternal |
c83f0bd5 K |
491 | void CacheManagerActionLegacy::run(StoreEntry *sentry) |
492 | { | |
26ac0430 | 493 | handler(sentry); |
c83f0bd5 | 494 | } |
832c08ab | 495 | /// \ingroup CacheManagerInternal |
2f53e904 K |
496 | CacheManagerAction::CacheManagerAction(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic) |
497 | { | |
498 | flags.pw_req = isPwReq; | |
499 | flags.atomic = isAtomic; | |
500 | action = xstrdup (anAction); | |
501 | desc = xstrdup (aDesc); | |
502 | } | |
832c08ab FC |
503 | /// \ingroup CacheManagerInternal |
504 | CacheManagerAction::~CacheManagerAction() | |
505 | { | |
2f53e904 K |
506 | xfree(action); |
507 | xfree(desc); | |
508 | } | |
509 | ||
832c08ab | 510 | /// \ingroup CacheManagerInternal |
2f53e904 K |
511 | CacheManagerActionLegacy::CacheManagerActionLegacy(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic, OBJH *aHandler) : CacheManagerAction(anAction, aDesc, isPwReq, isAtomic), handler(aHandler) |
512 | { | |
513 | } |