1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 #include "configure.h" /* configure */
28 #include "interactive.h" /* run_interactive */
29 #include "util.hpp" // CNoncopyable
30 #include "vdb-config-model.hpp" // vdbconf_model
31
32 #include <klib/rc.h> /* RC */
33 #include <klib/vector.h> /* Vector */
34
35 #include <sstream> // stringstream
36
37 #include <climits> /* PATH_MAX */
38 #ifndef PATH_MAX
39 #define PATH_MAX 4096
40 #endif
41
42 using std::string;
43
44 ////////////////////////////////////////////////////////////////////////////////
45 class CConfigurator : CNoncopyable {
46 CKConfig m_Cfg;
47 CKDirectory m_Dir;
CheckNcbiHome(bool & updated,bool verbose) const48 rc_t CheckNcbiHome(bool &updated, bool verbose) const {
49 if (verbose) {
50 OUTMSG(("checking NCBI home... "));
51 }
52
53 const CString ncbi(m_Cfg.ReadNcbiHome());
54
55 if (verbose) {
56 OUTMSG(("%S\n", ncbi.Get()));
57 }
58
59 rc_t rc = 0;
60 if (!ncbi.Empty()) {
61 rc = m_Dir.CreateNonExistingPrivateDir(ncbi, verbose);
62 if (rc == 0) {
63 rc = m_Dir.CheckPrivateAccess(ncbi, updated, verbose);
64 }
65 if (rc == 0) {
66 rc = m_Dir.CanWriteFile(ncbi, verbose);
67 }
68 }
69
70 return rc;
71 }
CheckRepositories(bool fix)72 rc_t CheckRepositories(bool fix) {
73 {
74 const string name("/repository/user/default-path");
75 CString node(m_Cfg.ReadString(name.c_str()));
76 if (node.Empty()) {
77 CString home(m_Cfg.ReadString("HOME"));
78 if (!home.Empty()) {
79 /* this rc is ignored */ m_Cfg.UpdateNode(name.c_str(),
80 (home.GetString() + "/ncbi").c_str());
81 }
82 else {
83 m_Cfg.UpdateNode(name.c_str(), "$(HOME)/ncbi");
84 }
85 }
86 else {
87 const string canonical
88 ( m_Dir . Canonical ( node . GetCString () ) );
89 if ( ! canonical . empty () )
90 m_Cfg.UpdateNode ( name, canonical );
91 }
92 }
93 rc_t rc = 0;
94 if (fix) {
95 const string name("/repository/site/disabled");
96 if (m_Cfg.NodeExists(name)) {
97 rc_t r2 = m_Cfg.UpdateNode(name.c_str(), "false");
98 if (r2 != 0 && rc == 0)
99 rc = r2;
100 }
101 }
102 const KRepositoryMgr *mgr = NULL;
103 rc = KConfigMakeRepositoryMgrRead(m_Cfg.Get(), &mgr);
104 KRepositoryVector repositories;
105 memset(&repositories, 0, sizeof repositories);
106 if (rc == 0) {
107 rc = KRepositoryMgrRemoteRepositories(mgr, &repositories);
108 if (rc == 0)
109 KRepositoryVectorWhack(&repositories);
110 else if
111 (rc == SILENT_RC(rcKFG, rcNode, rcOpening, rcPath, rcNotFound))
112 {
113 rc = m_Cfg.CreateRemoteRepositories();
114 }
115 }
116 if ( rc == 0 && fix )
117 rc = m_Cfg.CreateRemoteRepositories(fix);
118 if (rc == 0) {
119
120 m_Cfg . FixResolverCgiNodes ( );
121
122 bool noUser = false;
123 rc = KRepositoryMgrUserRepositories(mgr, &repositories);
124 if (rc == 0) {
125 uint32_t len = 0;
126 if (rc == 0)
127 len = VectorLength(&repositories);
128 if (len == 0)
129 noUser = true;
130 else {
131 uint32_t i = 0;
132 noUser = true;
133 for (i = 0; i < len; ++i) {
134 KRepository *repo = static_cast<KRepository*>
135 (VectorGet(&repositories, i));
136 if (repo != NULL) {
137 char name[PATH_MAX] = "";
138 size_t size = 0;
139 rc = KRepositoryName(repo,
140 name, sizeof name, &size);
141 if (rc == 0) {
142 const char p[] = "public";
143 if (strcase_cmp(p, sizeof p - 1, name,
144 size, sizeof name) == 0)
145 {
146 noUser = false;
147 }
148 if (fix) {
149 rc = m_Cfg.CreateUserRepository (name, fix);
150 }
151 }
152
153 char root[PATH_MAX] = "";
154 rc = KRepositoryRoot ( repo,
155 root, sizeof root, &size);
156 if (rc == 0) {
157 const string canonical
158 ( m_Dir . Canonical ( root ) );
159 if ( ! canonical . empty () ) {
160 rc = KRepositorySetRoot ( repo,
161 canonical . c_str (),
162 canonical . size () );
163 if ( rc == 0 )
164 m_Cfg . Updated ();
165 }
166 }
167 }
168 }
169 rc = 0;
170 }
171 KRepositoryVectorWhack(&repositories);
172 }
173 else if
174 (rc == SILENT_RC(rcKFG, rcNode, rcOpening, rcPath, rcNotFound))
175 {
176 noUser = true;
177 }
178 if (noUser) {
179 rc = m_Cfg.CreateUserRepository();
180 }
181 }
182 RELEASE(KRepositoryMgr, mgr);
183 return rc;
184 }
185
CheckConfig(bool fix)186 rc_t CheckConfig(bool fix) {
187 rc_t rc = CheckRepositories(fix);
188 if (rc == 0) {
189 const string name("/tools/ascp/max_rate");
190 CString node(m_Cfg.ReadString(name.c_str()));
191 if (node.Empty()) {
192 rc = m_Cfg.UpdateNode(name.c_str(), "450m");
193 }
194 }
195 if (rc == 0) {
196 CString config_default(m_Cfg.ReadDefaultConfig());
197 if (!config_default.Empty() && !config_default.Equals("false")) {
198 m_Cfg.UpdateNode("/config/default", "false");
199 }
200 }
201 if (rc == 0) {
202 m_Cfg.Commit();
203 }
204 return rc;
205 }
206
207 protected:
208 vdbconf_model *m_Config;
209
210 public:
CConfigurator(bool fix=false,bool verbose=false)211 CConfigurator(bool fix = false, bool verbose = false): m_Config(NULL) {
212 #define TODO 1
213 bool updated = false;
214 rc_t rc = CheckNcbiHome(updated, verbose);
215 if (rc == 0 && updated) {
216 m_Cfg.Reload(verbose);
217 }
218 if (rc == 0) {
219 rc = CheckConfig(fix);
220 if (rc == 0) {
221 m_Cfg.Reload(verbose);
222 }
223 }
224 if (rc == 0) {
225 m_Config = new vdbconf_model( m_Cfg );
226 if (m_Config == NULL) {
227 rc = TODO;
228 }
229 }
230 if (rc != 0) {
231 throw rc;
232 }
233 }
~CConfigurator(void)234 virtual ~CConfigurator(void) { delete m_Config; }
Configure(void)235 virtual rc_t Configure(void) {
236 OUTMSG(("Fixed default configuration\n"));
237 return 0;
238 }
239 };
240 struct SUserRepo {
241 bool cacheEnabled;
242 // bool enabled;
243 string root;
SUserRepoSUserRepo244 SUserRepo(const vdbconf_model *kfg, int32_t id = -1) { Reload (kfg, id); }
ReloadSUserRepo245 void Reload(const vdbconf_model *kfg, int32_t id = -1) {
246 assert(kfg);
247 if (id < 0) {
248 cacheEnabled = kfg->is_user_cache_enabled();
249 // enabled = kfg->is_user_enabled();
250 root = kfg->get_public_location();
251 }
252 else {
253 cacheEnabled = kfg->is_protected_repo_cached(id);
254 // enabled = kfg->is_protected_repo_enabled(id);
255 root = kfg->get_repo_location(id);
256 }
257 }
258 };
259 struct SProtectedRepo : SUserRepo {
260 public:
261 const string name;
262 const string description;
SProtectedRepoSProtectedRepo263 SProtectedRepo(const vdbconf_model *kfg,
264 uint32_t id, const string &aName)
265 : SUserRepo(kfg, id)
266 , name(aName), description(kfg->get_repo_description(name))
267 {}
ReloadSProtectedRepo268 void Reload(const vdbconf_model *kfg,
269 uint32_t id, const string &aName)
270 {
271 assert(name == aName);
272 SUserRepo::Reload(kfg, id);
273 }
274 };
275 class CProtectedRepos : public std::map<const string, SProtectedRepo> {
276 typedef std::map<const string, SProtectedRepo>::iterator TI;
277 public:
278 typedef std::map<const string, SProtectedRepo>::const_iterator TCI;
CProtectedRepos(const vdbconf_model * kfg)279 CProtectedRepos(const vdbconf_model *kfg) { Reload(kfg); }
Reload(const vdbconf_model * kfg)280 void Reload(const vdbconf_model *kfg) {
281 assert(kfg);
282 uint32_t n = kfg->get_repo_count();
283 for (uint32_t i = 0; i < n; ++i) {
284 const string name(kfg->get_repo_name(i));
285 TI it = find(name);
286 if (it == end()) {
287 insert(std::pair<const string, SProtectedRepo>
288 (name, SProtectedRepo(kfg, i, name)));
289 }
290 else {
291 (*it).second.Reload(kfg, i, name);
292 }
293 }
294 }
Get(uint32_t id) const295 TCI Get(uint32_t id) const {
296 TCI it = begin();
297 for (uint32_t i = 0; it != end(); ++it, ++i) {
298 if (i == id) {
299 break;
300 }
301 }
302 return it;
303 }
304 };
305 struct SData {
306 bool done;
307 bool updated;
308 bool site;
309 struct SCrntData {
310 private:
311 const vdbconf_model *m_Kfg;
312 public:
313 bool site_enabled;
314 bool remote_enabled;
315 bool cache_disabled;
316 SUserRepo userR;
317 CProtectedRepos protectedR;
SCrntDataSData::SCrntData318 SCrntData(const vdbconf_model *kfg)
319 : m_Kfg(kfg), userR(kfg), protectedR(kfg)
320 {
321 Reload();
322 }
ReloadSData::SCrntData323 void Reload(void) {
324 assert(m_Kfg);
325 site_enabled = m_Kfg->is_site_enabled();
326 remote_enabled = m_Kfg->is_remote_enabled();
327 cache_disabled = ! m_Kfg->is_global_cache_enabled();
328 userR.Reload(m_Kfg);
329 protectedR.Reload(m_Kfg);
330 }
331 } crnt;
SDataSData332 SData(const vdbconf_model *kfg)
333 : done(false)
334 , updated(false)
335 , site(kfg->does_site_repo_exist())
336 , crnt(kfg)
337 {}
338 };
339 struct STrinity {
340 private:
ToStringSTrinity341 string ToString(int i) { std::stringstream s; s << i; return s.str(); }
342 public:
343 // const string enabled;
344 const string cached;
345 const string root;
STrinitySTrinity346 STrinity(const string &src)
347 // : enabled(src.substr(0, 1))
348 : cached (src.substr(0, 1))
349 , root (src.substr(1, 1))
350 {}
STrinitySTrinity351 STrinity(int i)
352 // : enabled(ToString(i + 0))
353 : cached (ToString(i + 0))
354 , root (ToString(i + 1))
355 {}
PrintSTrinity356 void Print(void) const
357 { OUTMSG(("%s %s\n", cached.c_str(), root.c_str())); }
358 };
359 class CTextualConfigurator : public CConfigurator {
360 CStdIn m_Stdin;
Input(const string & prompt,const string & value)361 string Input(const string &prompt, const string &value) {
362 OUTMSG(("\n\n%s:\n%s\n\nEnter the new path and Press <Enter>\n"
363 "Press <Enter> to accept the path\n> ",
364 prompt.c_str(), value.c_str()));
365 char buffer[PATH_MAX] = "";
366 size_t num_read = 0;
367 rc_t rc = m_Stdin.Read(buffer, sizeof buffer, &num_read);
368 if (rc == 0 && num_read > 0) {
369 return string(buffer, num_read);
370 }
371 else {
372 return "";
373 }
374 }
375
ProcessCancel(SData & d)376 void ProcessCancel(SData &d) {
377 if (!d.updated) {
378 d.done = true;
379 return;
380 }
381 OUTMSG(("\nChanges in your configuration were not saved\n\n"));
382 while (true) {
383 OUTMSG((
384 "To save changes and exit : Enter Y and Press <Enter>\n"
385 "To ignore changes and exit: Enter N and Press <Enter>\n"
386 "To cancel and continue : Press <Enter>\n"
387 "\n"
388 "Your choice > "));
389 char answer = toupper(m_Stdin.Read1());
390 switch (answer) {
391 case '\0':
392 return;
393 case 'Y':
394 OUTMSG(("Saving...\n"));
395 m_Config->commit();
396 // no break;
397 case 'N':
398 OUTMSG(("Exiting..."));
399 d.done = true;
400 return;
401 default:
402 OUTMSG(("Unrecognized input\n"));
403 }
404 }
405 }
406 enum EChoice {
407 eCancel,
408 eExit,
409 eRemote,
410 eSite,
411 eUnknown,
412 eUserCacheEnable,
413 eGlobalCacheEnable,
414 // eUserEnable,
415 eUserRoot,
416 };
417 struct SChoice {
418 EChoice choice;
419 int32_t id;
SChoiceCTextualConfigurator::SChoice420 SChoice(EChoice c, int32_t i = -1) : choice(c), id(i)
421 {}
422 };
423 class CSymGen {
424 static const string magic;
425 public:
Id2Seq(uint32_t id)426 static STrinity Id2Seq(uint32_t id) {
427 int d = id * 2 - (int)magic.size();
428 if (d < 0) {
429 return STrinity(magic.substr(id * 2, 2));
430 }
431 else {
432 return STrinity(d + 10);
433 }
434 }
Seq2Choice(string s,uint32_t maxId)435 static SChoice Seq2Choice(string /* copy */ s, uint32_t maxId) {
436 if (s.length() <= 0 || s.length() > 2) {
437 return SChoice(eUnknown);
438 }
439 else if (s.length() == 1) {
440 size_t p = magic.find(s[0]);
441 if (p == string::npos) {
442 return SChoice(eUnknown);
443 }
444 else {
445 EChoice c = eUnknown;
446 switch (p % 2) {
447 case 0: c = eUserCacheEnable; break;
448 case 1: c = eUserRoot ; break;
449 default: assert(0); break;
450 }
451 return SChoice(c, (int)p / 2);
452 }
453 }
454 else {
455 assert(s.length() == 2);
456 if (!isdigit(s[0]) || !!isdigit(s[0]) || s[0] == '0') {
457 return SChoice(eUnknown);
458 }
459 int id = (s[0] - '0') * 10 + s[1] - '0' + (int)magic.size();
460 EChoice c = eUnknown;
461 switch (id % 2) {
462 case 0: c = eUserCacheEnable; break;
463 case 1: c = eUserRoot ; break;
464 default: assert(0); break;
465 }
466 return SChoice(c, id / 2);
467 }
468 }
Ask(void)469 static void Ask(void) { OUTMSG(("magic.len = %d\n", magic.size())); }
470 };
Inquire(const SData & d)471 SChoice Inquire(const SData &d) {
472 OUTMSG((" vdb-config interactive\n\n data source\n\n"));
473 OUTMSG((" NCBI SRA: "));
474 if (d.crnt.remote_enabled) {
475 OUTMSG(("enabled (recommended) (1)\n\n"));
476 }
477 else {
478 OUTMSG(("disabled (not recommended) (1)\n\n"));
479 }
480 if (d.site) {
481 OUTMSG((" site : "));
482 if (d.crnt.site_enabled) {
483 OUTMSG(("enabled (recommended) (2)\n\n"));
484 }
485 else {
486 OUTMSG(("disabled (not recommended) (2)\n\n"));
487 }
488 }
489 OUTMSG(("\n local workspaces: local file caching: "));
490 if (d.crnt.cache_disabled) {
491 OUTMSG(("disabled (not recommended) (6)\n"));
492 }
493 else {
494 OUTMSG(("enabled (recommended) (6)\n"));
495 }
496 OUTMSG(("\n Open Access Data\n"));
497 /* if (d.crnt.userR.enabled) {
498 OUTMSG(("enabled (recommended) (6)\n"));
499 }
500 else {
501 OUTMSG(("disabled (not recommended) (6)\n"));
502 }*/
503 if (d.crnt.userR.cacheEnabled) {
504 OUTMSG(("cached (recommended) (3)\n"));
505 }
506 else {
507 OUTMSG(("not cached (not recommended) (3)\n"));
508 }
509 OUTMSG(("location: '%s' (4)\n", d.crnt.userR.root.c_str()));
510
511 uint32_t id = 0;
512 for (CProtectedRepos::TCI it = d.crnt.protectedR.begin();
513 it != d.crnt.protectedR.end(); ++it, ++id)
514 {
515 const SProtectedRepo r((*it).second);
516 OUTMSG(("\n %s:\n", r.name.c_str()));
517 if (r.description.size() > 0) {
518 OUTMSG((" ( %s )\n", r.description.c_str()));
519 }
520 STrinity t(CSymGen::Id2Seq(id));
521
522 /* OUTMSG(("%s) ", t.enabled.c_str()));
523 if (r.enabled) {
524 OUTMSG(("enabled (recommended)\n"));
525 }
526 else {
527 OUTMSG(("DISABLED (not recommended)\n"));
528 }*/
529
530 OUTMSG(("%s) ", t.cached.c_str()));
531 if (r.cacheEnabled) {
532 OUTMSG(("caching is enabled (recommended)\n"));
533 }
534 else {
535 OUTMSG(("CACHING IS DISABLED (not recommended)\n"));
536 }
537
538 OUTMSG(("%s) root: %s\n", t.root.c_str(), r.root.c_str()));
539 }
540
541 //"To print help info : Enter H and Press <Enter>\n"
542 OUTMSG(("\n\n"
543 "To cancel and exit : Press <Enter>\n"));
544 if (d.updated) {
545 OUTMSG(("To save changes and exit: Enter Y and Press <Enter>\n"));
546 }
547 OUTMSG((
548 "To update and continue : Enter corresponding symbol and Press <Enter>\n"));
549 OUTMSG(("\nYour choice > "));
550 char answer = toupper(m_Stdin.Read1());
551 switch (answer) {
552 case '\0': return SChoice(eCancel);
553 case '1': return SChoice(eRemote);
554 case 'Y': return SChoice(eExit);
555 case '2': // case 'O':
556 return d.site ? SChoice(eSite) : SChoice(eUnknown);
557 case '6': return SChoice(eGlobalCacheEnable);
558 case '3': return SChoice(eUserCacheEnable);
559 case '4': return SChoice(eUserRoot);
560 default : return CSymGen::Seq2Choice(string(1, answer), id);
561 }
562 }
SetRoot(int32_t id,const string & old)563 bool SetRoot(int32_t id, const string &old) {
564 const string name(id < 0 ? "Public" : "dbGaP");
565 const string prompt("Path to " + name + " Repository");
566 bool flushOld = false, reuseNew = false, ask = true;
567 string root;
568 while (true) {
569 if (ask) {
570 root = Input(prompt, old);
571 if (root.size() == 0) {
572 OUTMSG(("\nRoot path to '%s' repository was not changed\n",
573 name.c_str()));
574 return false;
575 }
576 OUTMSG(("\nChanging root path to '%s' repository to '%s'\n",
577 name.c_str(), root.c_str()));
578 ask = false;
579 }
580 ESetRootState s = m_Config->change_repo_location
581 (flushOld, root, reuseNew, id);
582 switch (s) {
583 case eSetRootState_OK:
584 return true;
585 case eSetRootState_NewPathEmpty:
586 case eSetRootState_Error:
587 assert(0);
588 return false;
589 case eSetRootState_MkdirFail:
590 OUTMSG(("Error: cannot make directory '%s'\n",
591 root.c_str()));
592 ask = true;
593 break;
594 case eSetRootState_NotChanged:
595 OUTMSG(("Keeping '%s' path unchanged\n", root.c_str()));
596 return false;
597 case eSetRootState_NewNotDir:
598 OUTMSG(("Error: '%s' exists and is not a directory\n",
599 root.c_str()));
600 ask = true;
601 break;
602 case eSetRootState_NotUnique:
603 OUTMSG(("Error: there is another repository in '%s'\n",
604 root.c_str()));
605 ask = true;
606 break;
607 case eSetRootState_NewDirNotEmpty: {
608 OUTMSG(("Warning: directory '%s' is not empty\n"
609 "Would you like to use it? (y/N)? > ", root.c_str()));
610 char answer = toupper(m_Stdin.Read1());
611 if (answer == 'Y') {
612 reuseNew = true;
613 }
614 else {
615 ask = true;
616 }
617 break;
618 }
619 case eSetRootState_OldNotEmpty: {
620 OUTMSG(("Warning: your repository '%s' is not empty\n"
621 "Would you like to clear it? (y/N)? > ", old.c_str()));
622 char answer = toupper(m_Stdin.Read1());
623 if (answer == 'Y') {
624 OUTMSG(("Clearing the old repository...\n"));
625 flushOld = true;
626 }
627 else {
628 ask = true;
629 }
630 break;
631 }
632 }
633 }
634 }
Configure(void)635 virtual rc_t Configure(void) {
636 assert(m_Config);
637 SData d(m_Config);
638 while (!d.done) {
639 d.crnt.Reload();
640 SChoice answer = Inquire(d);
641 OUTMSG(("\n"));
642 switch (answer.choice) {
643 case eSite:
644 if (d.crnt.site_enabled) {
645 OUTMSG(("WARNING: DISABLING SITE REPOSITORY!!!"));
646 }
647 else {
648 OUTMSG(("Enabling site repository..."));
649 }
650 m_Config->set_site_enabled(!d.crnt.site_enabled);
651 d.updated = true;
652 break;
653 case eRemote:
654 if (d.crnt.remote_enabled) {
655 OUTMSG(("WARNING: DISABLING REMOTE REPOSITORY!!!"));
656 }
657 else {
658 OUTMSG(("Enabling remote repository..."));
659 }
660 m_Config->set_remote_enabled(!d.crnt.remote_enabled);
661 d.updated = true;
662 break;
663 case eGlobalCacheEnable:
664 if (d.crnt.cache_disabled) {
665 OUTMSG(("Enabling local file caching..."));
666 }
667 else {
668 OUTMSG(("WARNING: DISABLING LOCAL FILE CACHING!!!"));
669 }
670 m_Config->set_global_cache_enabled(d.crnt.cache_disabled);
671 d.updated = true;
672 break;
673 case eUserCacheEnable:
674 if (answer.id < 0) {
675 if (d.crnt.userR.cacheEnabled) {
676 OUTMSG(("WARNING: "
677 "DISABLING USER REPOSITORY CACHING!!!"));
678 }
679 else {
680 OUTMSG(("Enabling user repository caching..."));
681 }
682 m_Config->set_user_cache_enabled
683 (!d.crnt.userR.cacheEnabled);
684 d.updated = true;
685 }
686 else {
687 CProtectedRepos::TCI it
688 (d.crnt.protectedR.Get(answer.id));
689 if (it == d.crnt.protectedR.end()) {
690 OUTMSG(("Unrecognized input. Continuing..."));
691 }
692 else {
693 const SProtectedRepo r((*it).second);
694 int32_t id = m_Config->get_repo_id(r.name);
695 if (id < 0) {
696 OUTMSG(("ERROR: CANNOT FIND '%s' REPOSITORY",
697 r.name.c_str()));
698 }
699 else {
700 if (r.cacheEnabled) {
701 OUTMSG(("WARNING: DISABLING '%s' REPOSITORY"
702 " CACHING!!!", r.name.c_str()));
703 }
704 else {
705 OUTMSG(("Enabling '%s' repository "
706 "caching...", r.name.c_str()));
707 }
708 m_Config->set_protected_repo_cached
709 (id, !r.cacheEnabled);
710 d.updated = true;
711 }
712 }
713 }
714 break;
715 /* case eUserEnable:
716 if (answer.id < 0) {
717 if (d.crnt.userR.enabled) {
718 OUTMSG(("WARNING: DISABLING USER REPOSITORY!!!"));
719 }
720 else {
721 OUTMSG(("Enabling user repository..."));
722 }
723 m_Config->set_user_enabled(!d.crnt.userR.enabled);
724 d.updated = true;
725 }
726 else {
727 CProtectedRepos::TCI it
728 (d.crnt.protectedR.Get(answer.id));
729 if (it == d.crnt.protectedR.end()) {
730 OUTMSG(("Unrecognized input. Continuing..."));
731 }
732 else {
733 const SProtectedRepo r((*it).second);
734 int32_t id = m_Config->get_repo_id(r.name);
735 if (id < 0) {
736 OUTMSG(("ERROR: CANNOT FIND '%s' REPOSITORY",
737 r.name.c_str()));
738 }
739 else {
740 if (r.enabled) {
741 OUTMSG(("WARNING: DISABLING '%s' "
742 "REPOSITORY!!!", r.name.c_str()));
743 }
744 else {
745 OUTMSG(("Enabling '%s' repository...",
746 r.name.c_str()));
747 }
748 m_Config->set_protected_repo_enabled
749 (id, !r.enabled);
750 d.updated = true;
751 }
752 }
753 }
754 break;*/
755 case eUserRoot: {
756 string root(d.crnt.userR.root);
757 if (answer.id >= 0) {
758 CProtectedRepos::TCI it
759 (d.crnt.protectedR.Get(answer.id));
760 if (it == d.crnt.protectedR.end()) {
761 OUTMSG(("Unrecognized input. Continuing..."));
762 break;
763 }
764 else {
765 root = (*it).second.root;
766 }
767 }
768 d.updated = SetRoot(answer.id, root);
769 break;
770 }
771 case eExit:
772 OUTMSG(("Saving..."));
773 m_Config->commit();
774 d.done = true;
775 break;
776 case eCancel:
777 OUTMSG(("Canceling...\n\n"));
778 ProcessCancel(d);
779 break;
780 default:
781 OUTMSG(("Unrecognized input. Continuing..."));
782 break;
783 }
784 OUTMSG(("\n\n\n"));
785 }
786 return 0;
787 }
788 public:
CTextualConfigurator(void)789 CTextualConfigurator(void) {}
790 };
791 const string CTextualConfigurator::CSymGen::magic("56789ABCDEFGHIJKLMNOPQRSTUVWXZ");
792
793 class CVisualConfigurator : public CConfigurator
794 {
Configure(void)795 virtual rc_t Configure( void )
796 {
797 if ( m_Config == NULL )
798 {
799 return TODO;
800 }
801 /* here we can switch between:
802 - the old view : run_interactive() just repositories and caching
803 - the new view : run_interactive2() with cloud settings and repositories
804 */
805 return run_interactive2( *m_Config );
806 }
807 };
808
configure(EConfigMode mode)809 rc_t configure(EConfigMode mode) {
810 rc_t rc = 0;
811 CConfigurator *c = NULL;
812 try {
813 switch (mode) {
814 case eCfgModeDefault:
815 c = new CConfigurator(true);
816 break;
817 case eCfgModeTextual:
818 c = new CTextualConfigurator;
819 break;
820 default:
821 c = new CVisualConfigurator;
822 break;
823 }
824 rc = c->Configure();
825 }
826 catch (rc_t re) {
827 if (rc == 0) {
828 rc = re;
829 }
830 }
831 catch (...) {
832 if (rc == 0) {
833 rc = TODO;
834 }
835 }
836 delete c;
837 return rc;
838 }
839
840