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"
28
29 #include <cloud/manager.h> /* CloudMgrRelease */
30
31 #include <kapp/main.h>
32 #include <kapp/args-conv.h>
33
34 #include <vdb/vdb-priv.h> /* VDBManagerListExternalSchemaModules */
35 #include <vdb/manager.h> /* VDBManager */
36
37 #include <kfg/kfg-priv.h> /* KConfig */
38 #include <kfg/ngc.h> /* KNgcObjMakeFromFile */
39 #include <kfg/properties.h> /* KConfig_Get_Default_User_Path */
40 #include <kfg/repository.h> /* KConfigImportNgc */
41
42 #include <vfs/manager.h> /* VFSManagerMake */
43 #include <vfs/path-priv.h> /* KPathGetCWD */
44
45 #include <kfs/directory.h>
46 #include <kfs/file.h>
47 #include <kfs/impl.h> /* KDirectoryGetSysDir */
48 #include <kfs/kfs-priv.h> /* KSysDirOSPath */
49
50 #include <klib/log.h> /* LOGERR */
51 #include <klib/misc.h> /* is_iser_an_admin */
52 #include <klib/namelist.h>
53 #include <klib/out.h> /* OUTMSG */
54 #include <klib/printf.h> /* string_printf */
55 #include <klib/rc.h> /* RC */
56 #include <klib/text.h> /* strcase_cmp */
57
58 #include <sysalloc.h> /* redefine malloc etc calls */
59 #include <os-native.h> /* SHLX */
60
61 #include <assert.h>
62 #include <ctype.h> /* tolower */
63 #include <errno.h>
64 #include <stdio.h> /* scanf */
65 #include <stdlib.h> /* getenv */
66 #include <string.h> /* memset */
67
68 #include <limits.h> /* PATH_MAX */
69
70 #ifndef PATH_MAX
71 #define PATH_MAX 4096
72 #endif
73
74 #define DISP_RC(rc, msg) (void)((rc == 0) ? 0 : LOGERR(klogInt, rc, msg))
75 #define DISP_RC2(rc, name, msg) (void)((rc == 0) ? 0 : \
76 PLOGERR(klogInt, (klogInt, rc, \
77 "$(name): $(msg)", "name=%s,msg=%s", name, msg)))
78 #define RELEASE(type, obj) do { rc_t rc2 = type##Release(obj); \
79 if (rc2 && !rc) { rc = rc2; } obj = NULL; } while (false)
80
81 #define ALIAS_ALL "a"
82 #define OPTION_ALL "all"
83 static const char* USAGE_ALL[] = { "print all information [default]", NULL };
84
85 #define ALIAS_CFG "i"
86 #define OPTION_CFG "interactive"
87 static const char* USAGE_CFG[] = {
88 "create/update configuration",
89 NULL };
90
91 #define ALIAS_CFM NULL
92 #define OPTION_CFM "interactive-mode"
93 static const char* USAGE_CFM[] = {
94 "interactive mode: 'textual' or 'graphical' (default)",
95 NULL };
96
97 #define ALIAS_DIR "d"
98 #define OPTION_DIR "load-path"
99 static const char* USAGE_DIR[] = { "print load path", NULL };
100
101 #define ALIAS_ENV "e"
102 #define OPTION_ENV "env"
103 static const char* USAGE_ENV[] = { "print shell variables", NULL };
104
105 #define ALIAS_FIL "f"
106 #define OPTION_FIL "files"
107 static const char* USAGE_FIL[] = { "print loaded files", NULL };
108
109 #define ALIAS_FIX NULL
110 #define OPTION_FIX "restore-defaults"
111 static const char* USAGE_FIX[] =
112 { "create default or update existing user configuration", NULL };
113
114 #define ALIAS_MOD "m"
115 #define OPTION_MOD "modules"
116 static const char* USAGE_MOD[] = { "print external modules", NULL };
117
118 #define ALIAS_OUT "o"
119 #define OPTION_OUT "output"
120 static const char* USAGE_OUT[] = { "output type: one of (x n), "
121 "where 'x' is xml (default), 'n' is native", NULL };
122
123 #define ALIAS_PCF "p"
124 #define OPTION_PCF "cfg"
125 static const char* USAGE_PCF[] = { "print current configuration", NULL };
126
127 #define ALIAS_PRTCT NULL
128 #define OPTION_PRTCT "ignore-protected-repositories"
129 static const char* USAGE_PRTCT[] =
130 { "stop printing warning message when protected repository is found", NULL };
131
132 #define ALIAS_CDR NULL
133 #define OPTION_CDR "cfg-dir"
134 static const char* USAGE_CDR[]
135 = { "set directory to load configuration", NULL };
136
137 #define ALIAS_PRD NULL
138 #define OPTION_PRD "proxy-disable"
139 static const char* USAGE_PRD[] = { "enable/disable using HTTP proxy", NULL };
140
141 #define ALIAS_PRX NULL
142 #define OPTION_PRX "proxy"
143 static const char* USAGE_PRX[]
144 = { "set HTTP proxy server configuration", NULL };
145
146 #define ALIAS_ROOT NULL
147 #define OPTION_ROOT "root"
148 static const char* USAGE_ROOT[] =
149 { "enforce configuration update while being run by superuser", NULL };
150
151 #define ALIAS_SET "s"
152 #define OPTION_SET "set"
153 static const char* USAGE_SET[] = { "set configuration node value", NULL };
154
155 #define ALIAS_C_IN "C"
156 #define OPTION_C_IN "cloud-info"
157 static const char* USAGE_C_IN[]
158 = { "display cloud-releated information", NULL };
159
160 #define ALIAS_C_RI NULL
161 #define OPTION_C_RI "report-cloud-identity"
162 static const char* USAGE_C_RI[]
163 = { "give permission to report cloud instance identity", NULL };
164
165 #define ALIAS_S3_C NULL
166 #define OPTION_S3_C "accept-aws-charges"
167 static const char* USAGE_S3_C[]
168 = { "agree to accept charges for AWS usage", NULL };
169
170 #define ALIAS_S3_F NULL
171 #define OPTION_S3_F "set-aws-credentials"
172 static const char* USAGE_S3_F[] = { "select file with AWS credentials", NULL };
173
174 #define ALIAS_S3_P NULL
175 #define OPTION_S3_P "set-aws-profile"
176 static const char* USAGE_S3_P[] = { "set AWS profile", NULL };
177
178 #define ALIAS_GS_C NULL
179 #define OPTION_GS_C "accept-gcp-charges"
180 static const char* USAGE_GS_C[]
181 = { "agree to accept charges for GCP usage", NULL };
182
183 #define ALIAS_GS_F NULL
184 #define OPTION_GS_F "set-gcp-credentials"
185 static const char* USAGE_GS_F[] = { "select file with GCP credentials", NULL };
186
187 #define ALIAS_P_CW NULL
188 #define OPTION_P_CW "prefetch-to-cwd"
189 static const char* USAGE_P_CW[] = { "prefetch downloads to "
190 "current directory when public user repository is set (default: false)",
191 NULL };
192
193 #define ALIAS_P_UR NULL
194 #define OPTION_P_UR "prefetch-to-user-repo"
195 static const char* USAGE_P_UR[] = { "prefetch downloads to "
196 "public user repository when it is set (default)", NULL };
197
WorkspaceDirPathConv(const Args * args,uint32_t arg_index,const char * arg,size_t arg_len,void ** result,WhackParamFnP * whack)198 rc_t WorkspaceDirPathConv(const Args * args, uint32_t arg_index, const char * arg, size_t arg_len, void ** result, WhackParamFnP * whack)
199 {
200 uint32_t imp_count = 0;
201
202 /* rc_t rc = ArgsOptionCount(args, OPTION_IMP, &imp_count);
203 if (rc != 0)
204 return rc; */
205
206 // first parameter is a directory only if OPTION_IMP is present; otherwise it is a query
207 if (imp_count > 0)
208 {
209 return ArgsConvFilepath(args, arg_index, arg, arg_len, result, whack);
210 }
211
212 return ArgsConvDefault(args, arg_index, arg, arg_len, result, whack);
213 }
214
215 OptDef Options[] =
216 { /* needs_value, required, converter */
217 { OPTION_ALL, ALIAS_ALL, NULL, USAGE_ALL, 1, false, false, NULL }
218 , { OPTION_CDR, ALIAS_CDR, NULL, USAGE_CDR, 1, true , false, NULL }
219 , { OPTION_CFG, ALIAS_CFG, NULL, USAGE_CFG, 1, false, false, NULL }
220 , { OPTION_CFM, ALIAS_CFM, NULL, USAGE_CFM, 1, true , false, NULL }
221 , { OPTION_DIR, ALIAS_DIR, NULL, USAGE_DIR, 1, false, false, NULL }
222 , { OPTION_ENV, ALIAS_ENV, NULL, USAGE_ENV, 1, false, false, NULL }
223 , { OPTION_FIL, ALIAS_FIL, NULL, USAGE_FIL, 1, false, false, NULL }
224 , { OPTION_FIX, ALIAS_FIX, NULL, USAGE_FIX, 1, false, false, NULL }
225 , {OPTION_PRTCT,ALIAS_PRTCT,NULL,USAGE_PRTCT,1,false, false, NULL }
226 , { OPTION_MOD, ALIAS_MOD, NULL, USAGE_MOD, 1, false, false, NULL }
227 , { OPTION_OUT, ALIAS_OUT, NULL, USAGE_OUT, 1, true , false, NULL }
228 , { OPTION_C_IN,ALIAS_C_IN,NULL, USAGE_C_IN,1, false, false, NULL }
229 , { OPTION_C_RI,ALIAS_C_RI,NULL, USAGE_C_RI,1, true , false, NULL }
230 , { OPTION_S3_C,ALIAS_S3_C,NULL, USAGE_S3_C,1, true , false, NULL }
231 , { OPTION_S3_F,ALIAS_S3_F,NULL, USAGE_S3_F,1, true , false, NULL }
232 , { OPTION_S3_P,ALIAS_S3_P,NULL, USAGE_S3_P,1, true , false, NULL }
233 , { OPTION_GS_F,ALIAS_GS_F,NULL, USAGE_GS_F,1, true , false, NULL }
234 , { OPTION_GS_C,ALIAS_GS_C,NULL, USAGE_GS_C,1, true , false, NULL }
235 , { OPTION_P_CW,ALIAS_P_CW,NULL, USAGE_P_CW,1, false, false, NULL }
236 , { OPTION_P_UR,ALIAS_P_UR,NULL, USAGE_P_UR,1, false, false, NULL }
237 , { OPTION_PCF, ALIAS_PCF, NULL, USAGE_PCF, 1, false, false, NULL }
238 , { OPTION_PRD, ALIAS_PRD, NULL, USAGE_PRD, 1, true , false, NULL }
239 , { OPTION_PRX, ALIAS_PRX, NULL, USAGE_PRX, 1, true , false, NULL }
240 , { OPTION_SET, ALIAS_SET, NULL, USAGE_SET, 1, true , false, NULL }
241 , { OPTION_ROOT,ALIAS_ROOT,NULL, USAGE_ROOT,1, false, false, NULL }
242 };
243
244 ParamDef Parameters[] =
245 {
246 { WorkspaceDirPathConv }
247 };
248
UsageSummary(const char * progname)249 rc_t CC UsageSummary (const char * progname) {
250 return KOutMsg (
251 "Usage:\n"
252 " %s [options] [<query> ...]\n\n"
253 "Summary:\n"
254 " Manage VDB configuration\n"
255 , progname, progname);
256 }
257
Usage(const Args * args)258 rc_t CC Usage(const Args* args) {
259 rc_t rc = 0;
260
261 const char* progname = UsageDefaultName;
262 const char* fullpath = UsageDefaultName;
263
264 if (args == NULL) {
265 rc = RC(rcExe, rcArgv, rcAccessing, rcSelf, rcNull);
266 }
267 else {
268 rc = ArgsProgram(args, &fullpath, &progname);
269 }
270
271 UsageSummary(progname);
272
273 KOutMsg ("\nOptions:\n");
274
275 HelpOptionLine (ALIAS_ALL, OPTION_ALL, NULL, USAGE_ALL);
276 HelpOptionLine (ALIAS_PCF, OPTION_PCF, NULL, USAGE_PCF);
277 HelpOptionLine (ALIAS_FIL, OPTION_FIL, NULL, USAGE_FIL);
278 HelpOptionLine (ALIAS_DIR, OPTION_DIR, NULL, USAGE_DIR);
279 HelpOptionLine (ALIAS_ENV, OPTION_ENV, NULL, USAGE_ENV);
280 HelpOptionLine (ALIAS_MOD, OPTION_MOD, NULL, USAGE_MOD);
281 KOutMsg ("\n");
282 HelpOptionLine (ALIAS_SET, OPTION_SET, "name=value", USAGE_SET);
283 KOutMsg ("\n");
284 HelpOptionLine (ALIAS_CFG, OPTION_CFG, NULL, USAGE_CFG);
285 HelpOptionLine (ALIAS_CFM, OPTION_CFM, "mode", USAGE_CFM);
286 KOutMsg ("\n");
287 HelpOptionLine (ALIAS_FIX, OPTION_FIX, NULL, USAGE_FIX);
288 HelpOptionLine(ALIAS_PRTCT,OPTION_PRTCT,NULL,USAGE_PRTCT);
289 KOutMsg ("\n");
290 HelpOptionLine (ALIAS_OUT, OPTION_OUT, "x | n", USAGE_OUT);
291 KOutMsg ("\n");
292 HelpOptionLine(ALIAS_C_IN, OPTION_C_IN, NULL, USAGE_C_IN);
293 HelpOptionLine(ALIAS_C_RI, OPTION_C_RI, "yes | no", USAGE_C_RI);
294 HelpOptionLine(ALIAS_S3_C, OPTION_S3_C, "yes | no", USAGE_S3_C);
295 HelpOptionLine(ALIAS_S3_F, OPTION_S3_F, "path", USAGE_S3_F);
296 HelpOptionLine(ALIAS_S3_P, OPTION_S3_P, "profile", USAGE_S3_P);
297 HelpOptionLine(ALIAS_GS_C, OPTION_GS_C, "yes | no", USAGE_GS_C);
298 HelpOptionLine(ALIAS_GS_F, OPTION_GS_F, "path", USAGE_GS_F);
299 KOutMsg ("\n");
300 HelpOptionLine(ALIAS_P_CW, OPTION_P_CW, NULL, USAGE_P_CW);
301 HelpOptionLine(ALIAS_P_UR, OPTION_P_UR, NULL, USAGE_P_UR);
302 KOutMsg("\n");
303 HelpOptionLine (ALIAS_PRX, OPTION_PRX, "uri[:port]", USAGE_PRX);
304 HelpOptionLine (ALIAS_PRD, OPTION_PRD, "yes | no", USAGE_PRD);
305 KOutMsg ("\n");
306 HelpOptionLine (ALIAS_CDR, OPTION_CDR, "path", USAGE_CDR);
307 KOutMsg ("\n");
308 HelpOptionLine (ALIAS_ROOT,OPTION_ROOT,NULL, USAGE_ROOT);
309
310 KOutMsg ("\n");
311
312 HelpOptionsStandard ();
313
314 HelpVersion (fullpath, KAppVersion());
315
316 return rc;
317 }
318
319 const char UsageDefaultName[] = "vdb-config";
320
Indent(bool xml,int n)321 static void Indent(bool xml, int n) {
322 if (!xml)
323 { return; }
324 while (n--)
325 { OUTMSG((" ")); }
326 }
327
KConfigNodeReadData(const KConfigNode * self,char * buf,size_t blen,size_t * num_read)328 static rc_t KConfigNodeReadData(const KConfigNode* self,
329 char* buf, size_t blen, size_t* num_read)
330 {
331 rc_t rc = 0;
332 size_t remaining = 0;
333 assert(buf && blen && num_read);
334 rc = KConfigNodeRead(self, 0, buf, blen, num_read, &remaining);
335 assert(remaining == 0); /* TODO overflow check */
336 assert(*num_read <= blen);
337 return rc;
338 }
339
340 static
_printNodeData(const char * name,const char * data,size_t dlen)341 rc_t _printNodeData(const char *name, const char *data, size_t dlen)
342 {
343 bool secret = false;
344 {
345 const char d1[] = "download-ticket";
346 size_t l1 = sizeof d1 - 1;
347
348 const char d2[] = "aws_access_key_id";
349 size_t l2 = sizeof d2 - 1;
350
351 const char d3[] = "aws_secret_access_key";
352 size_t l3 = sizeof d3 - 1;
353
354 if ((string_cmp(name,
355 string_measure(name, NULL), d1, l1, (uint32_t)l1) == 0) ||
356 (string_cmp(name,
357 string_measure(name, NULL), d2, l2, (uint32_t)l2) == 0) ||
358 (string_cmp(name,
359 string_measure(name, NULL), d3, l3, (uint32_t)l3) == 0))
360 {
361 secret = true;
362 }
363 }
364
365 if (secret) {
366 const char *ellipsis = "";
367 const char replace[] =
368 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
369 if (dlen > 70) {
370 dlen = 70;
371 ellipsis = "...";
372 }
373 return OUTMSG(("%.*s%s", (uint32_t)dlen, replace, ellipsis));
374 }
375 else {
376 return OUTMSG(("%.*s", dlen, data));
377 }
378 }
379
380 #define VDB_CONGIG_OUTMSG(args) do { if (xml) { OUTMSG(args); } } while (false)
KConfigNodePrintChildNames(bool xml,const KConfigNode * self,const char * name,int indent,const char * aFullpath)381 static rc_t KConfigNodePrintChildNames(bool xml, const KConfigNode* self,
382 const char* name, int indent, const char* aFullpath)
383 {
384 rc_t rc = 0;
385 uint32_t count = 0;
386 int i = 0;
387 char buffer[8192] = "";
388 size_t num_read = 0;
389 bool hasChildren = false;
390 bool hasData = false;
391 const KConfigNode* node = NULL;
392 KNamelist* names = NULL;
393 bool beginsWithNumberinXml = false;
394 assert(self && name);
395
396 if (rc == 0)
397 { rc = KConfigNodeOpenNodeRead(self, &node, "%s", name); }
398 if (rc == 0) {
399 rc = KConfigNodeReadData(node, buffer, sizeof buffer, &num_read);
400 hasData = num_read > 0;
401 if (hasData) {
402 /* VDB_CONGIG_OUTMSG(("\n%s = \"%.*s\"\n\n", aFullpath, num_read, buffer)); */
403 }
404 }
405 if (rc == 0) {
406 rc = KConfigNodeListChild(node, &names);
407 }
408 if (rc == 0) {
409 rc = KNamelistCount(names, &count);
410 hasChildren = count;
411 }
412
413 Indent(xml, indent);
414 if (xml) {
415 beginsWithNumberinXml = isdigit(name[0]);
416 if (! beginsWithNumberinXml) {
417 VDB_CONGIG_OUTMSG(("<%s", name));
418 }
419 else {
420 /* XML node names cannot start with a number */
421 VDB_CONGIG_OUTMSG(("<_%s", name));
422 }
423 }
424 if (!hasChildren && !hasData) {
425 VDB_CONGIG_OUTMSG(("/>\n"));
426 }
427 else { VDB_CONGIG_OUTMSG((">"));
428 }
429 if (hasData) {
430 if (xml) {
431 _printNodeData(name, buffer, num_read);
432 }
433 else {
434 OUTMSG(("%s = \"", aFullpath));
435 _printNodeData(name, buffer, num_read);
436 OUTMSG(("\"\n"));
437 }
438 }
439 if (hasChildren)
440 { VDB_CONGIG_OUTMSG(("\n"));}
441
442 if (hasChildren) {
443 for (i = 0; i < (int)count && rc == 0; ++i) {
444 char* fullpath = NULL;
445 const char* name = NULL;
446 rc = KNamelistGet(names, i, &name);
447 if (rc == 0) {
448 size_t bsize = strlen(aFullpath) + 1 + strlen(name) + 1;
449 fullpath = malloc(bsize + 1);
450 if (fullpath == NULL) {
451 rc = RC
452 (rcExe, rcStorage, rcAllocating, rcMemory, rcExhausted);
453 }
454 else {
455 string_printf(fullpath, bsize, NULL,
456 "%s/%s", aFullpath, name);
457 }
458 }
459 if (rc == 0) {
460 rc = KConfigNodePrintChildNames
461 (xml, node, name, indent + 1, fullpath);
462 }
463 free(fullpath);
464 }
465 }
466
467 if (hasChildren)
468 { Indent(xml, indent); }
469 if (hasChildren || hasData)
470 {
471 if (! beginsWithNumberinXml) {
472 VDB_CONGIG_OUTMSG(("</%s>\n",name));
473 }
474 else {
475 VDB_CONGIG_OUTMSG(("</_%s>\n",name));
476 }
477 }
478
479 RELEASE(KNamelist, names);
480 RELEASE(KConfigNode, node);
481 return rc;
482 }
483
484 typedef enum {
485 eNotSet,
486 eFalse,
487 eTrue
488 } EState;
489
490 typedef struct Params {
491 Args* args;
492 uint32_t argsParamIdx;
493 uint32_t argsParamCnt;
494
495 const char *cfg_dir;
496
497 bool xml;
498
499 const char *setValue;
500
501 const char *ngc;
502
503 bool modeSetNode;
504 bool modeConfigure;
505 bool ignoreProtected;
506 EConfigMode configureMode;
507 bool modeCreate;
508 bool modeShowCfg;
509 bool modeShowEnv;
510 bool modeShowFiles;
511 bool modeShowLoadPath;
512 bool modeShowModules;
513 bool modeRoot;
514
515 bool showMultiple;
516
517 enum {
518 eUndefined,
519 eNo,
520 eYes
521 } proxyDisabled;
522 const char *proxy;
523
524 bool modeCloud; /* cloud-releated mode */
525 bool cloudInfo;
526 EState cloudReportIdentity;
527 EState s3AcceptCharges;
528 const char * s3Credentials;
529 const char * s3Profile;
530 EState gsAcceptCharges;
531 const char * gsCredentials;
532 EState prefetchToCwd;
533 } Params;
534
ParamsConstruct(int argc,char * argv[],Params * prm)535 static rc_t ParamsConstruct(int argc, char* argv[], Params* prm) {
536 rc_t rc = 0;
537 Args* args = NULL;
538 int count = 0;
539 assert(argc && argv && prm);
540 memset(prm, 0, sizeof *prm);
541 args = prm->args;
542 do {
543 const char* dummy = NULL;
544 uint32_t pcount = 0;
545 rc = ArgsMakeAndHandle2(&args, argc, argv, Parameters, sizeof Parameters / sizeof Parameters[0], 1, Options, sizeof Options / sizeof Options[0]);
546 if (rc) {
547 LOGERR(klogErr, rc, "While calling ArgsMakeAndHandle2");
548 break;
549 }
550
551 prm->args = args;
552 rc = ArgsParamCount(args, &prm->argsParamCnt);
553 if (rc) {
554 LOGERR(klogErr, rc, "Failure to get query parameter[s]");
555 break;
556 }
557 if (prm->argsParamCnt > 0) {
558 prm->modeShowCfg = true;
559 ++count;
560 }
561
562 { // OPTION_OUT
563 prm->xml = true;
564 rc = ArgsOptionCount(args, OPTION_OUT, &pcount);
565 if (rc) {
566 LOGERR(klogErr, rc, "Failure to get '" OPTION_OUT "' argument");
567 break;
568 }
569 if (pcount) {
570 rc = ArgsOptionValue(args, OPTION_OUT, 0, (const void **)&dummy);
571 if (rc) {
572 LOGERR(klogErr, rc, "Failure to get '" OPTION_OUT "' argument");
573 break;
574 }
575 if (!strcmp(dummy, "n")) {
576 prm->xml = false;
577 }
578 else if (strcmp(dummy, "x")) {
579 rc = RC(rcExe, rcArgv, rcParsing, rcParam, rcInvalid);
580 LOGERR(klogErr, rc, "Bad " OPTION_OUT " value");
581 break;
582 }
583 }
584 }
585 { // OPTION_ENV
586 rc = ArgsOptionCount(args, OPTION_ENV, &pcount);
587 if (rc) {
588 LOGERR(klogErr, rc, "Failure to get '" OPTION_ENV "' argument");
589 break;
590 }
591 if (pcount) {
592 prm->modeShowEnv = true;
593 ++count;
594 }
595 }
596 { // OPTION_CDR
597 rc = ArgsOptionCount(args, OPTION_CDR, &pcount);
598 if (rc != 0) {
599 LOGERR(klogErr, rc, "Failure to get '" OPTION_CDR "' argument");
600 break;
601 }
602 if (pcount > 0) {
603 rc = ArgsOptionValue
604 (args, OPTION_CDR, 0, (const void **)&prm->cfg_dir);
605 if (rc) {
606 LOGERR(klogErr, rc,
607 "Failure to get '" OPTION_CDR "' argument");
608 break;
609 }
610 }
611 }
612 { // OPTION_FIL
613 rc = ArgsOptionCount(args, OPTION_FIL, &pcount);
614 if (rc) {
615 LOGERR(klogErr, rc, "Failure to get '" OPTION_FIL "' argument");
616 break;
617 }
618 if (pcount > 0) {
619 prm->modeShowFiles = true;
620 ++count;
621 }
622 }
623 /* OPTION_MOD */
624 {
625 rc = ArgsOptionCount(args, OPTION_MOD, &pcount);
626 if (rc) {
627 LOGERR(klogErr, rc, "Failure to get '" OPTION_MOD "' argument");
628 break;
629 }
630 if (pcount) {
631 prm->modeShowModules = true;
632 ++count;
633 }
634 }
635 /* OPTION_PCF */
636 {
637 rc = ArgsOptionCount(args, OPTION_PCF, &pcount);
638 if (rc) {
639 LOGERR(klogErr, rc, "Failure to get '" OPTION_PCF "' argument");
640 break;
641 }
642 if (pcount) {
643 if (!prm->modeShowCfg) {
644 prm->modeShowCfg = true;
645 ++count;
646 }
647 }
648 }
649 { // OPTION_PRD
650 rc = ArgsOptionCount(args, OPTION_PRD, &pcount);
651 if (rc != 0) {
652 LOGERR(klogErr, rc, "Failure to get '" OPTION_PRD "' argument");
653 break;
654 }
655 if (pcount > 0) {
656 const char *dummy = NULL;
657 rc = ArgsOptionValue(args, OPTION_PRD, 0, (const void **)&dummy);
658 if (rc) {
659 LOGERR(klogErr, rc, "Failure to get '" OPTION_PRD "' argument");
660 break;
661 }
662 if (tolower(dummy[0]) == 'y') {
663 prm->proxyDisabled = eYes;
664 }
665 else if (tolower(dummy[0]) == 'n') {
666 prm->proxyDisabled = eNo;
667 }
668 }
669 }
670 { // OPTION_PRX
671 rc = ArgsOptionCount(args, OPTION_PRX, &pcount);
672 if (rc != 0) {
673 LOGERR(klogErr, rc, "Failure to get '" OPTION_PRX "' argument");
674 break;
675 }
676 if (pcount > 0) {
677 rc = ArgsOptionValue(args, OPTION_PRX, 0, (const void **)&prm->proxy);
678 if (rc) {
679 LOGERR(klogErr, rc, "Failure to get '" OPTION_PRX "' argument");
680 break;
681 }
682 }
683 }
684 { // OPTION_DIR
685 rc = ArgsOptionCount(args, OPTION_DIR, &pcount);
686 if (rc != 0) {
687 LOGERR(klogErr, rc, "Failure to get '" OPTION_DIR "' argument");
688 break;
689 }
690 if (pcount) {
691 prm->modeShowLoadPath = true;
692 ++count;
693 }
694 }
695 { // OPTION_ROOT
696 rc = ArgsOptionCount(args, OPTION_ROOT, &pcount);
697 if (rc != 0) {
698 LOGERR(klogErr, rc, "Failure to get '" OPTION_ROOT "' argument");
699 break;
700 }
701 if (pcount) {
702 prm->modeRoot = true;
703 }
704 }
705 { // OPTION_SET
706 rc = ArgsOptionCount(args, OPTION_SET, &pcount);
707 if (rc != 0) {
708 LOGERR(klogErr, rc, "Failure to get '" OPTION_SET "' argument");
709 break;
710 }
711 if (pcount) {
712 rc = ArgsOptionValue(args, OPTION_SET, 0, (const void **)&prm->setValue);
713 if (rc == 0) {
714 const char* p = strchr(prm->setValue, '=');
715 if (p == NULL || *(p + 1) == '\0') {
716 rc = RC(rcExe, rcArgv, rcParsing, rcParam, rcInvalid);
717 LOGERR(klogErr, rc, "Bad " OPTION_SET " value");
718 break;
719 }
720 prm->modeSetNode = true;
721 prm->modeCreate = prm->modeShowCfg = prm->modeShowEnv
722 = prm->modeShowFiles = prm->modeShowLoadPath
723 = prm->modeShowModules = false;
724 count = 1;
725 }
726 }
727 }
728 { // OPTION_FIX
729 rc = ArgsOptionCount(args, OPTION_FIX, &pcount);
730 if (rc) {
731 LOGERR(klogErr, rc, "Failure to get '" OPTION_FIX "' argument");
732 break;
733 }
734 if (pcount) {
735 prm->modeConfigure = true;
736 prm->modeShowCfg = false;
737 count = 1;
738 prm->configureMode = eCfgModeDefault;
739 }
740 }
741 /* OPTION_PRTCT */ {
742 const char * option = OPTION_PRTCT;
743 rc = ArgsOptionCount(args, option, &pcount);
744 if (rc != 0) {
745 PLOGERR(klogErr, (klogErr, rc,
746 "Failure to get '${opt}' argument", "opt=%s", option));
747 break;
748 }
749 if (pcount > 0)
750 prm->ignoreProtected = true;
751 }
752 /* OPTION_CFG */
753 {
754 rc = ArgsOptionCount(args, OPTION_CFG, &pcount);
755 if (rc) {
756 LOGERR(klogErr, rc, "Failure to get '" OPTION_CFG "' argument");
757 break;
758 }
759 if (pcount) {
760 #if 1
761 prm->modeConfigure = true;
762 prm->modeShowCfg = false;
763 count = 1;
764 prm->configureMode = eCfgModeVisual;
765
766 #else
767 const char* dummy = NULL;
768 rc = ArgsOptionValue(args, OPTION_CFG, 0, (const void **)&dummy);
769 if (rc) {
770 LOGERR(klogErr, rc, "Failure to get '" OPTION_CFG "' argument");
771 break;
772 }
773 prm->modeConfigure = true;
774 prm->modeShowCfg = false;
775 count = 1;
776 switch (dummy[0]) {
777 case 't':
778 prm->configureMode = eCfgModeTextual;
779 break;
780 default:
781 prm->configureMode = eCfgModeDefault;
782 break;
783 }
784 #endif
785 }
786 }
787 /* OPTION_CFM */
788 {
789 rc = ArgsOptionCount(args, OPTION_CFM, &pcount);
790 if (rc) {
791 LOGERR(klogErr, rc, "Failure to get '" OPTION_CFM "' argument");
792 break;
793 }
794 if (pcount) {
795 const char* dummy = NULL;
796 size_t dummy_len;
797 rc = ArgsOptionValue(args, OPTION_CFM, 0, (const void **)&dummy);
798 if (rc) {
799 LOGERR(klogErr, rc, "Failure to get '" OPTION_OUT "' argument");
800 break;
801 }
802 prm->modeShowCfg = false;
803 count = 1;
804 prm->modeConfigure = true;
805
806 dummy_len = strlen( dummy );
807 if ( dummy_len == 0 )
808 dummy_len = 1;
809
810 if ( strncmp( dummy, "textual", dummy_len ) == 0 )
811 prm->configureMode = eCfgModeTextual;
812 else if ( strncmp( dummy, "graphical", dummy_len ) == 0 )
813 prm->configureMode = eCfgModeVisual;
814 else
815 {
816 rc = RC( rcExe, rcArgv, rcEvaluating, rcParam, rcInvalid );
817 LOGERR(klogErr, rc, "Unrecognized '" OPTION_CFM "' argument");
818 break;
819 }
820 }
821 }
822 /********************************* cloud begin ********************************/
823 /* OPTION_C_IN */
824 {
825 rc = ArgsOptionCount(args, OPTION_C_IN, &pcount);
826 if (rc) {
827 LOGERR(klogErr, rc,
828 "Failure to get '" OPTION_C_IN "' argument");
829 break;
830 }
831 if (pcount > 0)
832 prm->cloudInfo = prm->modeCloud = true;
833 }
834 /* OPTION_C_RI */
835 {
836 rc = ArgsOptionCount(args, OPTION_C_RI, &pcount);
837 if (rc != 0) {
838 LOGERR(klogErr, rc,
839 "Failure to get '" OPTION_C_RI "' argument");
840 break;
841 }
842 if (pcount > 0) {
843 rc = ArgsOptionValue(args, OPTION_C_RI, 0,
844 (const void **)&dummy);
845 if (rc != 0) {
846 LOGERR(klogErr, rc,
847 "Failure to get '" OPTION_C_RI "' argument");
848 break;
849 }
850 if (strncasecmp(dummy, "y", 1) == 0)
851 prm->cloudReportIdentity = eTrue;
852 else
853 prm->cloudReportIdentity = eFalse;
854 prm->modeCloud = true;
855 }
856 }
857 /* OPTION_GS_C */
858 {
859 rc = ArgsOptionCount(args, OPTION_GS_C, &pcount);
860 if (rc != 0) {
861 LOGERR(klogErr, rc,
862 "Failure to get '" OPTION_GS_C "' argument");
863 break;
864 }
865 if (pcount > 0) {
866 rc = ArgsOptionValue(args, OPTION_GS_C, 0,
867 (const void **)&dummy);
868 if (rc != 0) {
869 LOGERR(klogErr, rc,
870 "Failure to get '" OPTION_GS_C "' argument");
871 break;
872 }
873 if (strcasecmp(dummy, "yes") == 0)
874 prm->gsAcceptCharges = eTrue;
875 else
876 prm->gsAcceptCharges = eFalse;
877 prm->modeCloud = true;
878 }
879 }
880 /* OPTION_GS_F */
881 {
882 rc = ArgsOptionCount(args, OPTION_GS_F, &pcount);
883 if (rc != 0) {
884 LOGERR(klogErr, rc,
885 "Failure to get '" OPTION_GS_F "' argument");
886 break;
887 }
888 if (pcount > 0) {
889 rc = ArgsOptionValue(args, OPTION_GS_F, 0, (const void **)
890 &prm->gsCredentials);
891 if (rc != 0) {
892 LOGERR(klogErr, rc,
893 "Failure to get '" OPTION_GS_F "' argument");
894 break;
895 }
896 prm->modeCloud = true;
897 }
898 }
899 /* OPTION_S3_C */
900 {
901 rc = ArgsOptionCount(args, OPTION_S3_C, &pcount);
902 if (rc != 0) {
903 LOGERR(klogErr, rc,
904 "Failure to get '" OPTION_S3_C "' argument");
905 break;
906 }
907 if (pcount > 0) {
908 rc = ArgsOptionValue(args, OPTION_S3_C, 0,
909 (const void **)&dummy);
910 if (rc != 0) {
911 LOGERR(klogErr, rc,
912 "Failure to get '" OPTION_S3_C "' argument");
913 break;
914 }
915 if (!strcasecmp(dummy, "yes"))
916 prm->s3AcceptCharges = eTrue;
917 else
918 prm->s3AcceptCharges = eFalse;
919 prm->modeCloud = true;
920 }
921 }
922 /* OPTION_S3_F */
923 {
924 rc = ArgsOptionCount(args, OPTION_S3_F, &pcount);
925 if (rc != 0) {
926 LOGERR(klogErr, rc,
927 "Failure to get '" OPTION_S3_F "' argument");
928 break;
929 }
930 if (pcount > 0) {
931 rc = ArgsOptionValue(args, OPTION_S3_F, 0, (const void **)
932 &prm->s3Credentials);
933 if (rc != 0) {
934 LOGERR(klogErr, rc,
935 "Failure to get '" OPTION_S3_F "' argument");
936 break;
937 }
938 prm->modeCloud = true;
939 }
940 }
941 /* OPTION_S3_P */
942 {
943 rc = ArgsOptionCount(args, OPTION_S3_P, &pcount);
944 if (rc != 0) {
945 LOGERR(klogErr, rc,
946 "Failure to get '" OPTION_S3_P "' argument");
947 break;
948 }
949 if (pcount > 0) {
950 rc = ArgsOptionValue(args, OPTION_S3_P, 0, (const void **)
951 &prm->s3Profile);
952 if (rc != 0) {
953 LOGERR(klogErr, rc,
954 "Failure to get '" OPTION_S3_P "' argument");
955 break;
956 }
957 prm->modeCloud = true;
958 }
959 }
960 /* OPTION_P_UR */
961 {
962 rc = ArgsOptionCount(args, OPTION_P_UR, &pcount);
963 if (rc != 0) {
964 LOGERR(klogErr, rc,
965 "Failure to get '" OPTION_P_UR "' argument");
966 break;
967 }
968 if (pcount > 0) {
969 prm->prefetchToCwd = eFalse;
970 prm->modeCloud = true;
971 }
972 }
973 /* OPTION_P_CW */
974 {
975 rc = ArgsOptionCount(args, OPTION_P_CW, &pcount);
976 if (rc != 0) {
977 LOGERR(klogErr, rc,
978 "Failure to get '" OPTION_P_CW "' argument");
979 break;
980 }
981 if (pcount > 0) {
982 prm->prefetchToCwd = eTrue;
983 prm->modeCloud = true;
984 }
985 }
986 /********************************* cloud end **********************************/
987 /* OPTION_ALL */
988 {
989 rc = ArgsOptionCount(args, OPTION_ALL, &pcount);
990 if (rc != 0) {
991 LOGERR(klogErr, rc, "Failure to get '" OPTION_ALL "' argument");
992 break;
993 }
994 if (pcount > 0
995 || ( !prm->modeConfigure
996 && !prm->ignoreProtected
997 && !prm->modeShowCfg
998 && ! prm->modeShowLoadPath
999 && !prm->modeShowEnv
1000 && !prm->modeShowFiles
1001 && !prm->modeShowModules
1002 && !prm->modeCreate
1003 && !prm->modeSetNode
1004 && !prm->modeCloud
1005 && prm->ngc == NULL
1006 && prm->proxy == NULL && prm->proxyDisabled == eUndefined))
1007 /* show all by default */
1008 {
1009 prm->modeShowCfg = prm->modeShowEnv = prm->modeShowFiles = true;
1010 count += 2;
1011 }
1012 }
1013 if (count > 1) {
1014 prm->showMultiple = true;
1015 }
1016 } while (false);
1017
1018 return rc;
1019 }
1020
ParamsGetNextParam(Params * prm,const char ** param)1021 static rc_t ParamsGetNextParam(Params* prm, const char** param) {
1022 rc_t rc = 0;
1023 assert(prm && param);
1024 *param = NULL;
1025 if (prm->argsParamIdx < prm->argsParamCnt) {
1026 rc = ArgsParamValue(prm->args, prm->argsParamIdx++, (const void **)param);
1027 if (rc)
1028 { LOGERR(klogErr, rc, "Failure retrieving query"); }
1029 }
1030 return rc;
1031 }
1032
ParamsDestruct(Params * prm)1033 static rc_t ParamsDestruct(Params* prm) {
1034 rc_t rc = 0;
1035 assert(prm);
1036 RELEASE(Args, prm->args);
1037 return rc;
1038 }
1039
1040 static
privReadStdinLine(char * buf,size_t bsize,bool destroy)1041 rc_t privReadStdinLine(char* buf, size_t bsize, bool destroy)
1042 {
1043 rc_t rc = 0;
1044 static const KFile* std_in = NULL;
1045 static uint64_t pos = 0;
1046 size_t num_read = 0;
1047 if (destroy) {
1048 RELEASE(KFile, std_in);
1049 pos = 0;
1050 return rc;
1051 }
1052 if (std_in == NULL) {
1053 rc = KFileMakeStdIn(&std_in);
1054 if (rc != 0) {
1055 DISP_RC(rc, "KFileMakeStdIn");
1056 return rc;
1057 }
1058 }
1059 rc = KFileRead(std_in, pos, buf, bsize, &num_read);
1060 DISP_RC(rc, "KFileRead");
1061 pos += num_read;
1062 if (num_read) {
1063 bool done = false;
1064 buf[num_read] = '\0';
1065 while (num_read > 0 && !done) {
1066 switch (buf[num_read - 1]) {
1067 case '\n':
1068 case '\r':
1069 buf[--num_read] = '\0';
1070 break;
1071 default:
1072 done = true;
1073 break;
1074 }
1075 }
1076 }
1077 return rc;
1078 }
1079
ReadStdinLine(char * buf,size_t bsize)1080 static rc_t ReadStdinLine(char* buf, size_t bsize) {
1081 return privReadStdinLine(buf, bsize, false);
1082 }
1083
DestroyStdin(void)1084 static rc_t DestroyStdin(void)
1085 { return privReadStdinLine(NULL, 0, true); }
1086
In(const char * prompt,const char * def,char ** read)1087 static rc_t In(const char* prompt, const char* def, char** read) {
1088 rc_t rc = 0;
1089 char buf[PATH_MAX + 1];
1090 assert(prompt && read);
1091 *read = NULL;
1092 while (rc == 0 && (read[0] == NULL || read[0][0] == '\0')) {
1093 OUTMSG(("%s", prompt));
1094 if (def)
1095 { OUTMSG((" [%s]", def)); }
1096 OUTMSG((": "));
1097 rc = ReadStdinLine(buf, sizeof buf);
1098 if (rc == 0) {
1099 while (strlen(buf) > 0) {
1100 char c = buf[strlen(buf) - 1];
1101 if (c == '\n' || c == '\r')
1102 { buf[strlen(buf) - 1] = '\0'; }
1103 else
1104 { break; }
1105 }
1106 if (buf[0] == '\0' && def != NULL) {
1107 string_copy_measure(buf, sizeof buf, def);
1108 }
1109 if (buf[0]) {
1110 *read = strdup(buf);
1111 if (*read == NULL) {
1112 rc = RC
1113 (rcExe, rcStorage, rcAllocating, rcMemory, rcExhausted);
1114 }
1115 }
1116 }
1117 }
1118 return rc;
1119 }
1120
scan_config_dir(const KDirectory * dir,uint32_t type,const char * name,void * data)1121 static rc_t CC scan_config_dir(const KDirectory* dir,
1122 uint32_t type, const char* name, void* data)
1123 {
1124 rc_t rc = 0;
1125 assert(data);
1126 switch (type) {
1127 case kptFile:
1128 case kptFile | kptAlias: {
1129 size_t sz = strlen(name);
1130 if (sz >= 5 && strcase_cmp(&name[sz - 4], 4, ".kfg", 4, 4) == 0) {
1131 string_copy_measure(data, PATH_MAX + 1, name);
1132 /* from CreateConfig..KDirectoryVVisit call */
1133 rc = RC(rcExe, rcDirectory, rcListing, rcFile, rcExists);
1134 }
1135 break;
1136 }
1137 }
1138 return rc;
1139 }
1140
CreateConfig(char * argv0)1141 static rc_t CreateConfig(char* argv0) {
1142 const KFile* std_in = NULL;
1143 KDirectory* native = NULL;
1144 KDirectory* dir = NULL;
1145 rc_t rc = 0;
1146 char* location = NULL;
1147 char* mod = NULL;
1148 char* wmod = NULL;
1149 char* refseq = NULL;
1150 if (rc == 0) {
1151 rc = KDirectoryNativeDir(&native);
1152 }
1153 if (rc == 0) {
1154 const char* def = NULL;
1155 char cwd[PATH_MAX + 1] = "";
1156 const char* home = getenv("HOME");
1157 if (home)
1158 { def = home; }
1159 else {
1160 rc = KDirectoryResolvePath ( native, true, cwd, sizeof cwd, "." );
1161 if (rc == 0 && cwd[0])
1162 { def = cwd; }
1163 else
1164 { def = "."; }
1165 }
1166 while (rc == 0) {
1167 char buffer[PATH_MAX + 1];
1168 rc = In("Specify configuration files directory", def, &location);
1169 if (rc == 0) {
1170 rc = KDirectoryOpenDirUpdate(native, &dir, false, "%s", location);
1171 if (rc == 0) {
1172 rc = KDirectoryVisit
1173 (dir, false, scan_config_dir, buffer, ".");
1174 if (rc != 0) {
1175 if (rc ==
1176 RC(rcExe, rcDirectory, rcListing, rcFile, rcExists)
1177 && buffer[0])
1178 {
1179 PLOGERR(klogErr, (klogErr, rc,
1180 "Configuration file found: $(dir)/$(name)",
1181 "dir=%s,name=%s", location, buffer));
1182 rc = 0;
1183 buffer[0] = '\0';
1184 continue;
1185 }
1186 else {
1187 PLOGERR(klogErr, (klogErr, rc, "$(dir)/$(name)",
1188 "dir=%s,name=%s", location, buffer));
1189 }
1190 }
1191 break;
1192 }
1193 else if (GetRCObject(rc) == (enum RCObject)rcPath &&
1194 (GetRCState(rc) == rcIncorrect || GetRCState(rc) == rcNotFound))
1195 {
1196 PLOGERR(klogErr,
1197 (klogErr, rc, "$(path)", "path=%s", location));
1198 rc = 0;
1199 }
1200 else { DISP_RC(rc, location); }
1201 }
1202 }
1203 }
1204 while (rc == 0) {
1205 const KDirectory* dir = NULL;
1206 rc = In("Specify refseq installation directory", NULL, &refseq);
1207 if (rc != 0)
1208 { break; }
1209 rc = KDirectoryOpenDirRead(native, &dir, false, "%s", refseq);
1210 if (rc == 0) {
1211 RELEASE(KDirectory, dir);
1212 break;
1213 }
1214 else if (GetRCObject(rc) == (enum RCObject)rcPath
1215 && GetRCState(rc) == rcIncorrect)
1216 {
1217 PLOGERR(klogErr,
1218 (klogErr, rc, "$(path)", "path=%s", refseq));
1219 rc = 0;
1220 }
1221 DISP_RC(rc, refseq);
1222 }
1223 if (rc == 0) {
1224 char buffer[512];
1225 const char path[] = "vdb-config.kfg";
1226 uint64_t pos = 0;
1227 KFile* f = NULL;
1228 rc = KDirectoryCreateFile(dir, &f, false, 0664, kcmCreate, "%s", path);
1229 DISP_RC(rc, path);
1230 if (rc == 0) {
1231 int n = snprintf(buffer, sizeof buffer,
1232 "refseq/servers = \"%s\"\n", refseq);
1233 if (n >= sizeof buffer) {
1234 rc = RC(rcExe, rcFile, rcWriting, rcBuffer, rcInsufficient);
1235 }
1236 else {
1237 size_t num_writ = 0;
1238 rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ);
1239 pos += num_writ;
1240 }
1241 }
1242 if (rc == 0) {
1243 const char buffer[] = "refseq/volumes = \".\"\n";
1244 size_t num_writ = 0;
1245 rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ);
1246 pos += num_writ;
1247 }
1248 if (rc == 0 && mod && mod[0]) {
1249 int n = snprintf(buffer, sizeof buffer,
1250 "vdb/module/paths = \"%s\"\n", mod);
1251 if (n >= sizeof buffer) {
1252 rc = RC(rcExe, rcFile, rcWriting, rcBuffer, rcInsufficient);
1253 }
1254 else {
1255 size_t num_writ = 0;
1256 rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ);
1257 pos += num_writ;
1258 }
1259 }
1260 if (rc == 0 && wmod && wmod[0]) {
1261 int n = snprintf(buffer, sizeof buffer,
1262 "vdb/wmodule/paths = \"%s\"\n", wmod);
1263 if (n >= sizeof buffer) {
1264 rc = RC(rcExe, rcFile, rcWriting, rcBuffer, rcInsufficient);
1265 }
1266 else {
1267 size_t num_writ = 0;
1268 rc = KFileWrite(f, pos, buffer, strlen(buffer), &num_writ);
1269 pos += num_writ;
1270 }
1271 }
1272 RELEASE(KFile, f);
1273 }
1274 free(mod);
1275 free(wmod);
1276 free(refseq);
1277 free(location);
1278 RELEASE(KDirectory, dir);
1279 RELEASE(KDirectory, native);
1280 RELEASE(KFile, std_in);
1281 DestroyStdin();
1282 return rc;
1283 }
1284
1285 #if 0
1286 static rc_t ShowModules(const KConfig* cfg, const Params* prm) {
1287 rc_t rc = 0;
1288 #ifdef _STATIC
1289 OUTMSG(("<!-- Modules are not used in static build -->\n"));
1290 #else
1291 const VDBManager* mgr = NULL;
1292 KNamelist* list = NULL;
1293 OUTMSG(("<!-- Modules -->\n"));
1294 rc = VDBManagerMakeRead(&mgr, NULL);
1295 DISP_RC(rc, "while calling VDBManagerMakeRead");
1296 if (rc == 0) {
1297 rc = VDBManagerListExternalSchemaModules(mgr, &list);
1298 DISP_RC(rc, "while calling VDBManagerListExternalSchemaModules");
1299 }
1300 if (rc == 0) {
1301 uint32_t count = 0;
1302 rc = KNamelistCount(list, &count);
1303 DISP_RC(rc, "while calling KNamelistCount "
1304 "on VDBManagerListExternalSchemaModules result");
1305 if (rc == 0) {
1306 int64_t i = 0;
1307 for (i = 0; i < count && rc == 0; ++i) {
1308 const char* name = NULL;
1309 rc = KNamelistGet(list, i, &name);
1310 DISP_RC(rc, "while calling KNamelistGet "
1311 "on VDBManagerListExternalSchemaModules result");
1312 if (rc == 0) {
1313 OUTMSG(("%s\n", name));
1314 }
1315 }
1316 }
1317 }
1318 OUTMSG(("\n"));
1319 RELEASE(KNamelist, list);
1320 RELEASE(VDBManager, mgr);
1321 #endif
1322 return rc;
1323 }
1324 #endif
1325
KConfig_IgnoreProtected(KConfig * self)1326 static rc_t KConfig_IgnoreProtected(KConfig * self) {
1327 rc_t rc = KConfigWriteBool(self, "/repository/user/ignore-protected", true);
1328 if (rc == 0)
1329 rc = KConfigCommit(self);
1330 return rc;
1331 }
1332
SetNode(KConfig * cfg,const Params * prm)1333 static rc_t SetNode(KConfig* cfg, const Params* prm) {
1334 rc_t rc = 0;
1335
1336 KConfigNode* node = NULL;
1337 char* name = NULL;
1338 char* val = NULL;
1339
1340 assert(cfg && prm && prm->setValue);
1341
1342 if (is_iser_an_admin() && !prm->modeRoot) {
1343 rc = RC(rcExe, rcNode, rcUpdating, rcCondition, rcViolated);
1344 LOGERR(klogErr, rc, "Warning: "
1345 "normally this application should not be run as root/superuser");
1346 }
1347
1348 name = strdup(prm->setValue);
1349 if (name == NULL)
1350 { return RC(rcExe, rcStorage, rcAllocating, rcMemory, rcExhausted); }
1351
1352 val = strchr(name, '=');
1353 if (val == NULL || *(val + 1) == '\0') {
1354 rc_t rc = RC(rcExe, rcArgv, rcParsing, rcParam, rcInvalid);
1355 LOGERR(klogErr, rc, "Bad " OPTION_SET " value");
1356 }
1357
1358 if (rc == 0) {
1359 *(val++) = '\0';
1360
1361 rc = KConfigOpenNodeUpdate(cfg, &node, "%s", name);
1362 if (rc != 0) {
1363 PLOGERR(klogErr, (klogErr, rc,
1364 "Cannot open node '$(name)' for update", "name=%s", name));
1365 }
1366 }
1367
1368 if (rc == 0) {
1369 assert(val);
1370 rc = KConfigNodeWrite(node, val, strlen(val));
1371 if (rc != 0) {
1372 PLOGERR(klogErr, (klogErr, rc,
1373 "Cannot write value '$(val) to node '$(name)'",
1374 "val=%s,name=%s", val, name));
1375 }
1376 }
1377
1378 if (rc == 0) {
1379 rc = KConfigCommit(cfg);
1380 DISP_RC(rc, "while calling KConfigCommit");
1381 }
1382
1383 free(name);
1384 name = NULL;
1385
1386 RELEASE(KConfigNode, node);
1387 return rc;
1388 }
1389
SetProxy(KConfig * cfg,const Params * prm)1390 static rc_t SetProxy(KConfig *cfg, const Params *prm) {
1391 rc_t rc = 0;
1392
1393 bool disabled = false;
1394 bool set = false;
1395 bool disableSet = false;
1396
1397 assert(prm);
1398
1399 switch (prm->proxyDisabled) {
1400 case eNo:
1401 disabled = false;
1402 break;
1403 case eYes:
1404 disabled = true;
1405 break;
1406 default:
1407 break;
1408 }
1409
1410 if (prm->proxy != NULL) {
1411 rc = KConfig_Set_Http_Proxy_Path(cfg, prm->proxy);
1412 set = true;
1413
1414 if (rc == 0 && prm->proxyDisabled == eUndefined) {
1415 rc = KConfig_Set_Http_Proxy_Enabled(cfg, true);
1416 }
1417 }
1418
1419 if (prm->proxyDisabled != eUndefined) {
1420 rc_t r2 = KConfig_Set_Http_Proxy_Enabled(cfg, ! disabled);
1421 disableSet = true;
1422 if (r2 != 0 && rc == 0) {
1423 rc = r2;
1424 }
1425 }
1426
1427 if (rc == 0) {
1428 rc = KConfigCommit(cfg);
1429 DISP_RC(rc, "while calling KConfigCommit");
1430 }
1431 if (rc == 0) {
1432 if (set) {
1433 OUTMSG(("Use HTTP proxy server configuration '%s'\n", prm->proxy));
1434 }
1435 if (disableSet) {
1436 OUTMSG(("HTTP proxy was %s\n", disabled ? "disabled" : "enabled"));
1437 }
1438 }
1439 else {
1440 LOGERR(klogErr, rc, "Failed to update HTTP proxy configuration");
1441 }
1442
1443 return rc;
1444 }
1445
ShowConfig(const KConfig * cfg,Params * prm)1446 static rc_t ShowConfig(const KConfig* cfg, Params* prm) {
1447 rc_t rc = 0;
1448 bool hasAny = false;
1449 bool hasQuery = false;
1450 bool xml = true;
1451 assert(cfg && prm);
1452 xml = prm->xml;
1453 while (rc == 0) {
1454 KNamelist* names = NULL;
1455 const KConfigNode* node = NULL;
1456 uint32_t count = 0;
1457 uint32_t i = 0;
1458 int indent = 0;
1459 const char* root = NULL;
1460 const char* nodeName = NULL;
1461 size_t nodeNameL = 1;
1462 rc = ParamsGetNextParam(prm, &root);
1463 if (rc == 0) {
1464 if (root == NULL) {
1465 if (hasQuery)
1466 { break; }
1467 else
1468 { root = "/"; }
1469 }
1470 else { hasQuery = true; }
1471 assert(root);
1472 }
1473 if (rc == 0) {
1474 int64_t len = strlen(root);
1475 assert(len > 0);
1476 while (len > 0) {
1477 if (root[len - 1] == '/')
1478 { --len; }
1479 else { break; }
1480 }
1481 assert(len >= 0);
1482 if (len == 0) {
1483 root += strlen(root) - 1;
1484 nodeName = root;
1485 }
1486 else {
1487 char *c = memrchr(root, '/', len);
1488 if (c != NULL) {
1489 nodeName = c + 1;
1490 }
1491 else {
1492 nodeName = root;
1493 }
1494 }
1495 assert(nodeName && nodeName[0]);
1496 nodeNameL = strlen(nodeName);
1497 while (nodeNameL > 1 && nodeName[nodeNameL - 1] == '/')
1498 { --nodeNameL; }
1499 }
1500
1501 if (rc == 0) {
1502 rc = KConfigOpenNodeRead(cfg, &node, "%s", root);
1503 DISP_RC(rc, root);
1504 }
1505 if (rc == 0) {
1506 rc = KConfigNodeListChild(node, &names);
1507 }
1508 if (rc == 0) {
1509 rc = KNamelistCount(names, &count);
1510 }
1511 if (rc == 0 && count == 0) {
1512 char buf[512] = "";
1513 size_t num_read = 0;
1514 rc = KConfigNodeReadData(node, buf, sizeof buf, &num_read);
1515 if (rc == 0 && num_read > 0) {
1516 if (prm->showMultiple)
1517 { OUTMSG(("<!-- Configuration node %s -->\n", root)); }
1518 if (xml) {
1519 VDB_CONGIG_OUTMSG(("<%.*s>", nodeNameL, nodeName));
1520 VDB_CONGIG_OUTMSG(("%.*s", (int)num_read, buf));
1521 VDB_CONGIG_OUTMSG(("</%.*s>\n", nodeNameL, nodeName));
1522 }
1523 else {
1524 OUTMSG(("%.*s = \"%.*s\"\n",
1525 nodeNameL, nodeName, (int)num_read, buf));
1526 }
1527 hasAny = true;
1528 }
1529 }
1530 else {
1531 if (rc == 0) {
1532 if (nodeName[0] != '/') {
1533 if (prm->showMultiple)
1534 { OUTMSG(("<!-- Configuration node %s -->\n", root)); }
1535 VDB_CONGIG_OUTMSG(("<%.*s>\n", nodeNameL, nodeName));
1536 } else {
1537 if (prm->showMultiple)
1538 { OUTMSG(("<!-- Current configuration -->\n")); }
1539 VDB_CONGIG_OUTMSG(("<Config>\n"));
1540 }
1541 hasAny = true;
1542 ++indent;
1543 }
1544 for (i = 0; i < count && rc == 0; ++i) {
1545 const char* name = NULL;
1546 if (rc == 0)
1547 { rc = KNamelistGet(names, i, &name); }
1548 if (rc == 0) {
1549 char* fullname = NULL;
1550 if (strcmp(root, "/") == 0) {
1551 size_t bsize = strlen(name) + 2;
1552 fullname = malloc(bsize);
1553 if (fullname == NULL) {
1554 rc = RC(rcExe,
1555 rcStorage, rcAllocating, rcMemory, rcExhausted);
1556 }
1557 string_printf(fullname, bsize, NULL, "/%s", name);
1558 }
1559 else {
1560 size_t sz = strlen(root) + 2 + strlen(name);
1561 size_t num_writ = 0;
1562 fullname = malloc(sz);
1563 if (fullname == NULL) {
1564 rc = RC(rcExe,
1565 rcStorage, rcAllocating, rcMemory, rcExhausted);
1566 }
1567 rc = string_printf(fullname, sz, &num_writ,
1568 "%s/%s", root, name);
1569 assert(num_writ + 1 == sz);
1570 }
1571 if (rc == 0) {
1572 rc = KConfigNodePrintChildNames
1573 (xml, node, name, indent, fullname);
1574 hasAny = true;
1575 }
1576 free(fullname);
1577 fullname = NULL;
1578 }
1579 }
1580 if (rc == 0) {
1581 if (nodeName[0] != '/') {
1582 VDB_CONGIG_OUTMSG(("</%.*s>\n", nodeNameL, nodeName));
1583 }
1584 else {
1585 VDB_CONGIG_OUTMSG(("</Config>\n"));
1586 }
1587 }
1588 }
1589
1590 RELEASE(KConfigNode, node);
1591 RELEASE(KNamelist, names);
1592
1593 if (rc == 0) {
1594 if (hasAny) {
1595 OUTMSG(("\n"));
1596 }
1597 else if (nodeNameL > 0 && nodeName != NULL) {
1598 VDB_CONGIG_OUTMSG(("<%.*s/>\n", nodeNameL, nodeName));
1599 }
1600 }
1601
1602 if (!hasQuery)
1603 { break; }
1604 }
1605
1606 return rc;
1607 }
1608
ShowFiles(const KConfig * cfg,const Params * prm)1609 static rc_t ShowFiles(const KConfig* cfg, const Params* prm) {
1610 rc_t rc = 0;
1611 bool hasAny = false;
1612 uint32_t count = 0;
1613 KNamelist* names = NULL;
1614 rc = KConfigListIncluded(cfg, &names);
1615 if (rc == 0) {
1616 rc = KNamelistCount(names, &count);
1617 }
1618 if (rc == 0) {
1619 uint32_t i = 0;
1620
1621 if (prm->showMultiple) {
1622 if (prm->xml) {
1623 OUTMSG(("<ConfigurationFiles>\n"));
1624 }
1625 else {
1626 OUTMSG(("<!-- Configuration files -->\n"));
1627 }
1628 hasAny = true;
1629 }
1630
1631 for (i = 0; i < count && rc == 0; ++i) {
1632 const char* name = NULL;
1633 if (rc == 0)
1634 rc = KNamelistGet(names, i, &name);
1635 if (rc == 0) {
1636 OUTMSG(("%s\n", name));
1637 hasAny = true;
1638 }
1639 }
1640 }
1641 if (prm->showMultiple && prm->xml) {
1642 OUTMSG(("</ConfigurationFiles>"));
1643 }
1644
1645 if (rc == 0 && hasAny) {
1646 OUTMSG(("\n"));
1647 }
1648
1649 RELEASE(KNamelist, names);
1650
1651 return rc;
1652 }
1653
ShowEnv(const Params * prm)1654 static void ShowEnv(const Params* prm) {
1655 bool hasAny = false;
1656 const char * env_list [] = {
1657 "KLIB_CONFIG",
1658 "LD_LIBRARY_PATH",
1659 "NCBI_HOME",
1660 "NCBI_SETTINGS",
1661 "NCBI_VDB_CONFIG",
1662 "VDBCONFIG",
1663 "VDB_CONFIG",
1664 };
1665 int i = 0;
1666
1667 if (prm->showMultiple) {
1668 if (prm->xml) {
1669 OUTMSG(("<Environment>\n"));
1670 }
1671 else {
1672 OUTMSG(("<!-- Environment -->\n"));
1673 }
1674 hasAny = true;
1675 }
1676
1677 for (i = 0; i < sizeof env_list / sizeof env_list [ 0 ]; ++ i ) {
1678 const char *eval = getenv ( env_list [ i ] );
1679 if (eval) {
1680 OUTMSG(("%s=%s\n", env_list [ i ], eval));
1681 hasAny = true;
1682 }
1683 }
1684 if (prm->showMultiple && prm->xml) {
1685 OUTMSG(("</Environment>"));
1686 }
1687 if (hasAny) {
1688 OUTMSG(("\n"));
1689 }
1690 else {
1691 OUTMSG(("Environment variables are not found\n"));
1692 }
1693 }
1694
_VFSManagerSystem2PosixPath(const VFSManager * self,const char * system,char posix[PATH_MAX])1695 static rc_t _VFSManagerSystem2PosixPath(const VFSManager *self,
1696 const char *system, char posix[PATH_MAX])
1697 {
1698 VPath *path = NULL;
1699 rc_t rc = VFSManagerMakeSysPath(self, &path, system);
1700 if (rc == 0) {
1701 size_t written;
1702 rc = VPathReadPath(path, posix, PATH_MAX, &written);
1703 }
1704 RELEASE(VPath, path);
1705 return rc;
1706 }
1707
DefaultPepoLocation(const KConfig * cfg,uint32_t id,char * buffer,size_t bsize)1708 static rc_t DefaultPepoLocation(const KConfig *cfg,
1709 uint32_t id, char *buffer, size_t bsize)
1710 {
1711 rc_t rc = 0;
1712 char home[PATH_MAX] = "";
1713 size_t written = 0;
1714 assert(buffer && bsize);
1715 rc = KConfig_Get_Default_User_Path(cfg, home, sizeof home, &written);
1716 if (rc == 0 && written > 0) {
1717 rc = string_printf(buffer, bsize, &written, "%s/dbGaP-%u", home, id);
1718 if (rc == 0) {
1719 return rc;
1720 }
1721 }
1722
1723 rc = KConfig_Get_Home(cfg, home, sizeof home, &written);
1724 if (rc == 0 && written > 0) {
1725 rc = string_printf(buffer, bsize, &written,
1726 "%s/ncbi/dbGaP-%u", home, id);
1727 if (rc == 0) {
1728 return rc;
1729 }
1730 }
1731
1732 {
1733 VFSManager *vmgr = NULL;
1734 rc = VFSManagerMake(&vmgr);
1735 if (rc == 0) {
1736 const char *home = getenv("HOME");
1737 if (home == NULL) {
1738 home = getenv("USERPROFILE");
1739 }
1740 if (home == NULL) {
1741 #define TODO 1
1742 rc = TODO;
1743 }
1744 else {
1745 size_t num_writ = 0;
1746 char posix[PATH_MAX] = "";
1747 rc = _VFSManagerSystem2PosixPath(vmgr, home, posix);
1748 if (rc == 0) {
1749 rc = string_printf(buffer, bsize, &num_writ,
1750 "%s/ncbi/dbGaP-%u", posix, id);
1751 if (rc == 0) {
1752 return rc;
1753 }
1754 }
1755 }
1756 }
1757 RELEASE(VFSManager, vmgr);
1758 }
1759
1760 return rc;
1761 }
1762
DoImportNgc(KConfig * cfg,Params * prm,const char ** newRepoParentPath,uint32_t * result_flags)1763 static rc_t DoImportNgc(KConfig *cfg, Params *prm,
1764 const char **newRepoParentPath, uint32_t *result_flags)
1765 {
1766 rc_t rc = 0;
1767 KDirectory *dir = NULL;
1768 const KFile *src = NULL;
1769 const KNgcObj *ngc = NULL;
1770 static char buffer[PATH_MAX] = "";
1771 const char *root = NULL;
1772
1773 assert(prm);
1774 if (rc == 0) {
1775 rc = KDirectoryNativeDir(&dir);
1776 }
1777 if (rc == 0) {
1778 rc = KDirectoryOpenFileRead(dir, &src, "%s", prm->ngc);
1779 }
1780 if (rc == 0) {
1781 rc = KNgcObjMakeFromFile(&ngc, src);
1782 }
1783 RELEASE(KFile, src);
1784
1785 if (rc == 0) {
1786 uint32_t id = 0;
1787 rc = KNgcObjGetProjectId(ngc, &id);
1788 if (rc == 0) {
1789 const char *p = NULL;
1790 rc = ParamsGetNextParam(prm, &p);
1791 if (rc == 0 && p != NULL) {
1792 rc = KDirectoryResolvePath(dir, true, buffer, sizeof buffer, p);
1793 if (rc == 0) {
1794 root = buffer;
1795 }
1796 }
1797 else {
1798 rc = DefaultPepoLocation(cfg, id, buffer, sizeof buffer);
1799 if (rc == 0) {
1800 root = buffer;
1801 }
1802 }
1803 }
1804 }
1805 RELEASE(KDirectory, dir);
1806 if (rc == 0) {
1807 rc = KConfigImportNgc ( cfg, prm -> ngc, root, newRepoParentPath );
1808 }
1809 RELEASE(KNgcObj, ngc);
1810 return rc;
1811 }
1812
ImportNgc(KConfig * cfg,Params * prm)1813 static rc_t ImportNgc(KConfig *cfg, Params *prm) {
1814 const char *newRepoParentPath = NULL;
1815 uint32_t result_flags = 0;
1816 rc_t rc = 0;
1817 assert(prm);
1818 rc = DoImportNgc(cfg, prm, &newRepoParentPath, &result_flags);
1819 DISP_RC2(rc, "cannot import ngc file", prm->ngc);
1820 if ( rc == 0 ) {
1821 rc = KConfigCommit(cfg);
1822 }
1823 if (rc == 0) {
1824 #if WINDOWS
1825 char ngcPath[PATH_MAX] = "";
1826 char system[MAX_PATH] = "";
1827 #endif
1828 KDirectory *wd = NULL;
1829 const char *ngc = prm->ngc;
1830 rc_t rc = KDirectoryNativeDir(&wd);
1831 #if WINDOWS
1832 if (rc == 0) {
1833 rc = KDirectoryPosixStringToSystemString(wd,
1834 system, sizeof system, "%s", newRepoParentPath);
1835 if (rc == 0) {
1836 newRepoParentPath = system;
1837 }
1838 rc = KDirectoryPosixStringToSystemString(wd,
1839 ngcPath, sizeof ngcPath, "%s", ngc);
1840 if (rc == 0) {
1841 ngc = ngcPath;
1842 }
1843 }
1844 #endif
1845 if (wd) {
1846 if (KDirectoryPathType(wd, newRepoParentPath)
1847 == kptNotFound)
1848 {
1849 KDirectoryCreateDir(wd, 0775,
1850 kcmCreate | kcmParents, newRepoParentPath);
1851 }
1852 }
1853
1854 OUTMSG ( ( "%s was imported.\nRepository directory is: '%s'.\n",
1855 ngc, newRepoParentPath ) );
1856 RELEASE(KDirectory, wd);
1857 }
1858 return rc;
1859 }
1860
1861 static
CloudSetReportIdentity(KConfig * cfg,EState value,bool * set)1862 rc_t CloudSetReportIdentity(KConfig * cfg, EState value, bool * set) {
1863 rc_t rc = 0;
1864 if (value == eNotSet)
1865 return rc;
1866 rc = KConfig_Set_Report_Cloud_Instance_Identity(cfg, value == eTrue);
1867 if (rc == 0) {
1868 assert(set);
1869 *set = true;
1870 OUTMSG(("Report Cloud Instance Identity was set to %s\n",
1871 value == eTrue ? "true" : "false"));
1872 }
1873 return rc;
1874 }
1875
1876 static
S3SetAcceptCharges(KConfig * cfg,EState value,bool * set)1877 rc_t S3SetAcceptCharges(KConfig * cfg, EState value, bool * set) {
1878 rc_t rc = 0;
1879 if (value == eNotSet)
1880 return rc;
1881 rc = KConfig_Set_User_Accept_Aws_Charges(cfg, value == eTrue);
1882 if (rc == 0) {
1883 assert(set);
1884 *set = true;
1885 OUTMSG(("Accept Charges for AWS Usage was set to %s\n",
1886 value == eTrue ? "true" : "false"));
1887 }
1888 return rc;
1889 }
1890
S3SetCredentialsFile(KConfig * cfg,const char * aValue,bool * set)1891 static rc_t S3SetCredentialsFile(KConfig * cfg, const char * aValue,
1892 bool * set)
1893 {
1894 rc_t rc = 0;
1895 const char * value = aValue;
1896 if (value == NULL)
1897 return rc;
1898 if (value[0] == ' ' && value[1] == '\0')
1899 value = "";
1900 rc = KConfig_Set_Aws_Credential_File(cfg, value);
1901 if (rc == 0) {
1902 assert(set);
1903 *set = true;
1904 OUTMSG(("Path to AWS Credentials File was set to '%s'\n", value));
1905 }
1906 return rc;
1907 }
1908
1909 static
S3SetProfile(KConfig * cfg,const char * aValue,bool * set)1910 rc_t S3SetProfile(KConfig * cfg, const char * aValue, bool * set)
1911 {
1912 rc_t rc = 0;
1913 const char * value = aValue;
1914 if (value == NULL)
1915 return rc;
1916 if (value[0] == ' ' && value[1] == '\0')
1917 value = "";
1918 rc = KConfig_Set_Aws_Profile(cfg, value);
1919 if (rc == 0) {
1920 assert(set);
1921 *set = true;
1922 OUTMSG(("AWS Profile was set to '%s'\n", value));
1923 }
1924 return rc;
1925 }
1926
1927 static
GsSetAcceptCharges(KConfig * cfg,EState value,bool * set)1928 rc_t GsSetAcceptCharges(KConfig * cfg, EState value, bool * set)
1929 {
1930 rc_t rc = 0;
1931 if (value == eNotSet)
1932 return rc;
1933 rc = KConfig_Set_User_Accept_Gcp_Charges(cfg, value == eTrue);
1934 if (rc == 0) {
1935 assert(set);
1936 *set = true;
1937 OUTMSG(("Accept Charges for GCP Usage was set to %s\n",
1938 value == eTrue ? "true" : "false"));
1939 }
1940 return rc;
1941 }
1942
GsSetCredentialsFile(KConfig * cfg,const char * aValue,bool * set)1943 static rc_t GsSetCredentialsFile(KConfig * cfg, const char * aValue,
1944 bool * set)
1945 {
1946 rc_t rc = 0;
1947 const char * value = aValue;
1948 if (value == NULL)
1949 return rc;
1950 if (value[0] == ' ' && value[1] == '\0')
1951 value = "";
1952 rc = KConfig_Set_Gcp_Credential_File(cfg, value);
1953 if (rc == 0) {
1954 assert(set);
1955 *set = true;
1956 OUTMSG(("Path to GCP Credentials File was set to '%s'\n", value));
1957 }
1958 return rc;
1959 }
1960
1961 static
SetPrefetchDownload(KConfig * cfg,EState value,bool * set)1962 rc_t SetPrefetchDownload(KConfig * cfg, EState value, bool * set)
1963 {
1964 rc_t rc = 0;
1965 if (value == eNotSet)
1966 return rc;
1967 rc = KConfig_Set_Prefetch_Download_To_Cache(cfg, value == eFalse);
1968 if (rc == 0) {
1969 assert(set);
1970 *set = true;
1971 OUTMSG(("Prefetch will download to %s "
1972 "when Public User Repository is set\n",
1973 value == eTrue ? "Current Directory" : "User Repository"));
1974 }
1975 return rc;
1976 }
1977
CloudInfo(const KConfig * cfg,const Params * prm)1978 static rc_t CloudInfo(const KConfig * cfg, const Params * prm) {
1979 bool value = false;
1980 char buff[PATH_MAX] = "";
1981
1982 CloudMgr * mgr = NULL;
1983 rc_t rc = CloudMgrMake(&mgr, cfg, NULL);
1984
1985 CloudProviderId cloud_provider = cloud_provider_none;
1986 rc = CloudMgrCurrentProvider(mgr, &cloud_provider);
1987
1988 if (rc == 0 && cloud_provider != cloud_provider_none) {
1989 OUTMSG((
1990 "Cloud Environment:\n"
1991 "Current Cloud: %s\n", CloudProviderAsString(cloud_provider)));
1992 }
1993
1994 if (rc == 0)
1995 OUTMSG(("Cloud Settings:\n\n"));
1996
1997 if (rc == 0 && cloud_provider != cloud_provider_none) {
1998 rc = KConfig_Get_Report_Cloud_Instance_Identity(cfg, &value);
1999 if (rc == 0)
2000 OUTMSG(("Report Cloud Instance Identity: %s\n",
2001 value ? "yes" : "no"));
2002 }
2003
2004 if (rc == 0)
2005 OUTMSG(("AWS:\n"));
2006
2007 if (rc == 0) {
2008 rc = KConfig_Get_User_Accept_Aws_Charges(cfg, &value);
2009 if (rc == 0)
2010 OUTMSG((" Accept Charges for AWS Usage: %s\n",
2011 value ? "yes" : "no"));
2012 }
2013
2014 if (rc == 0) {
2015 rc = KConfig_Get_Aws_Credential_File(cfg, buff, sizeof buff, NULL);
2016 if (rc == 0 && buff[0] != '\0')
2017 OUTMSG((" AWS Credentials File: '%s'\n", buff));
2018 else if (rc == SILENT_RC(rcKFG, rcNode, rcOpening, rcPath, rcNotFound))
2019 rc = 0;
2020 }
2021
2022 if (rc == 0) {
2023 rc = KConfig_Get_Aws_Profile(cfg, buff, sizeof buff, NULL);
2024 if (rc == 0)
2025 OUTMSG((" AWS Profile: '%s'\n", buff));
2026 }
2027
2028 if (rc == 0)
2029 OUTMSG(("\nGCP:\n"));
2030
2031 if (rc == 0) {
2032 rc = KConfig_Get_User_Accept_Gcp_Charges(cfg, &value);
2033 if (rc == 0)
2034 OUTMSG((" Accept Charges for CGP Usage: %s\n",
2035 value ? "yes" : "no"));
2036 }
2037
2038 if (rc == 0) {
2039 rc = KConfig_Get_Gcp_Credential_File(cfg, buff, sizeof buff, NULL);
2040 if (rc == 0 && buff[0] != '\0')
2041 OUTMSG((" GCP Credentials File: '%s'\n", buff));
2042 else if (rc == SILENT_RC(rcKFG, rcNode, rcOpening, rcPath, rcNotFound))
2043 rc = 0;
2044 }
2045
2046 if (rc == 0) {
2047 OUTMSG(("\n\nTools:\n"));
2048 rc = KConfig_Get_Prefetch_Download_To_Cache(cfg, &value);
2049 if (rc == 0)
2050 OUTMSG((" Prefetch downloads to %s\n",
2051 value
2052 ? "Public User Repository when it is set\n"
2053 : "Current Directory when Public User Repository is set\n"));
2054 }
2055
2056 if (rc == 0)
2057 OUTMSG(("\n"
2058 "To change Cloud-related Settings run:\n"
2059 " vdb-config --interactive\n"
2060 "\n"
2061 "Cloud-related Command-Line Arguments:\n"
2062 " vdb-config --cloud-info\n\n"));
2063 if (rc == 0 && cloud_provider != cloud_provider_none)
2064 OUTMSG((
2065 " vdb-config --report-cloud-identity <yes|no>\n"));
2066 if (rc == 0)
2067 OUTMSG((
2068 " vdb-config --accept-aws-charges <yes|no>\n"
2069 " vdb-config --set-aws-credentials <Path to AWS Credentials File>\n"
2070 " vdb-config --set-aws-profile <AWS Profile>\n"
2071 " vdb-config --accept-gcp-charges <yes|no>\n"
2072 " vdb-config --set-gcp-credentials <Path to GCP Credentials File>\n"
2073 "\n"
2074 " vdb-config --prefetch-to-cwd\n"
2075 " vdb-config --prefetch-to-user-repo\n"
2076 "\n"
2077 " vdb-config --help\n"
2078 ));
2079
2080 RELEASE(CloudMgr, mgr);
2081
2082 return rc;
2083 }
2084
ProcessCloud(KConfig * cfg,const Params * prm)2085 static rc_t ProcessCloud(KConfig * cfg, const Params * prm) {
2086 rc_t rc = 0;
2087
2088 bool set = false;
2089
2090 assert(prm);
2091
2092 if (rc == 0)
2093 rc = CloudSetReportIdentity(cfg, prm->cloudReportIdentity, &set);
2094
2095 if (rc == 0)
2096 rc = S3SetAcceptCharges(cfg, prm->s3AcceptCharges, &set);
2097
2098 if (rc == 0)
2099 rc = S3SetCredentialsFile(cfg, prm->s3Credentials, &set);
2100
2101 if (rc == 0)
2102 rc = S3SetProfile(cfg, prm->s3Profile, &set);
2103
2104 if (rc == 0)
2105 rc = GsSetAcceptCharges(cfg, prm->gsAcceptCharges, &set);
2106
2107 if (rc == 0)
2108 rc = GsSetCredentialsFile(cfg, prm->gsCredentials, &set);
2109
2110 if (rc == 0)
2111 rc = SetPrefetchDownload(cfg, prm->prefetchToCwd, &set);
2112
2113 if (rc == 0 && set )
2114 rc = KConfigCommit(cfg);
2115
2116 if (rc == 0 && prm->cloudInfo)
2117 rc = CloudInfo(cfg, prm);
2118
2119 return rc;
2120 }
2121
KMain(int argc,char * argv[])2122 rc_t CC KMain(int argc, char* argv[]) {
2123 rc_t rc = 0;
2124
2125 Params prm;
2126 KConfig* cfg = NULL;
2127 bool configured = false;
2128
2129 if (rc == 0)
2130 rc = ParamsConstruct(argc, argv, &prm);
2131
2132 if (rc == 0 && prm.showMultiple && prm.xml)
2133 OUTMSG(("<VdbConfig>\n"));
2134
2135 if (rc == 0) {
2136 if (prm.modeConfigure) {
2137 rc = configure(prm.configureMode);
2138 configured = true;
2139 }
2140 }
2141
2142 if (rc == 0) {
2143 const KDirectory *d = NULL;
2144 KDirectory * n = NULL;
2145 rc = KDirectoryNativeDir ( & n );
2146 if (prm.cfg_dir != NULL) {
2147 if (rc == 0) {
2148 rc = KDirectoryOpenDirRead(n, &d, false, prm.cfg_dir);
2149 DISP_RC2(rc, "while opening", prm.cfg_dir);
2150 }
2151 }
2152 if (rc == 0) {
2153 rc = KConfigMake(&cfg, d);
2154 DISP_RC(rc, "while calling KConfigMake");
2155 }
2156
2157 if ( rc == 0 && ! configured ) {
2158 char home [ PATH_MAX ] = "";
2159 size_t written = 0;
2160 rc = KConfig_Get_Default_User_Path ( cfg, home, sizeof home,
2161 & written );
2162 if ( rc == 0 ) {
2163 char resolved [ PATH_MAX ] = "";
2164 rc_t r2 = KDirectoryResolvePath ( n, true, resolved,
2165 sizeof resolved, home );
2166 if ( r2 == 0 ) {
2167 size_t size = string_measure ( home, NULL );
2168 if ( string_cmp ( home, size, resolved,
2169 string_measure ( resolved, NULL ), size ) != 0 )
2170 {
2171 r2 = KConfig_Set_Default_User_Path ( cfg, resolved );
2172 if ( r2 == 0 ) {
2173 KConfigCommit ( cfg );
2174 KConfigRelease ( cfg );
2175 rc = KConfigMake ( &cfg, d );
2176 DISP_RC ( rc, "while re-calling KConfigMake" );
2177 }
2178 }
2179 }
2180 }
2181 else
2182 rc = 0;
2183 }
2184
2185 RELEASE ( KDirectory, d );
2186 RELEASE ( KDirectory, n );
2187
2188 if ( ! configured ) {
2189 if (prm.ngc)
2190 rc = ImportNgc(cfg, &prm);
2191 else if (prm.modeSetNode) {
2192 rc_t rc3 = SetNode(cfg, &prm);
2193 if (rc3 != 0 && rc == 0)
2194 rc = rc3;
2195 }
2196 }
2197
2198 if (prm.proxy != NULL || prm.proxyDisabled != eUndefined) {
2199 rc_t rc3 = SetProxy(cfg, &prm);
2200 if (rc3 != 0 && rc == 0)
2201 rc = rc3;
2202 }
2203
2204 if (prm.modeShowCfg) {
2205 rc_t rc3 = ShowConfig(cfg, &prm);
2206 if (rc3 != 0 && rc == 0)
2207 rc = rc3;
2208 }
2209
2210 if (prm.modeShowFiles) {
2211 rc_t rc3 = ShowFiles(cfg, &prm);
2212 if (rc3 != 0 && rc == 0)
2213 rc = rc3;
2214 }
2215
2216 if (prm.modeShowLoadPath) {
2217 const char* path = NULL;
2218 rc_t rc3 = KConfigGetLoadPath(cfg, &path);
2219 if (rc3 == 0) {
2220 if (path != NULL && path[0]) {
2221 OUTMSG(("%s\n", path));
2222 }
2223 }
2224 else if (rc == 0) {
2225 rc = rc3;
2226 }
2227 }
2228
2229 if (prm.modeCloud) {
2230 rc_t r = ProcessCloud(cfg, &prm);
2231 if (rc == 0 && r != 0)
2232 rc = r;
2233 }
2234
2235 if (prm.ignoreProtected) {
2236 rc_t r = KConfig_IgnoreProtected(cfg);
2237 if (rc == 0 && r != 0)
2238 rc = r;
2239 }
2240 }
2241
2242 if (prm.modeShowEnv) {
2243 ShowEnv(&prm);
2244 }
2245
2246 if (rc == 0 && prm.showMultiple && prm.xml) {
2247 OUTMSG(("</VdbConfig>\n"));
2248 }
2249
2250 RELEASE(KConfig, cfg);
2251
2252 if (rc == 0 && prm.modeCreate) {
2253 rc = CreateConfig(argv[0]);
2254 }
2255
2256 ParamsDestruct(&prm);
2257 return rc;
2258 }
2259
2260 /************************************* EOF ************************************/
2261