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 "vdb-config-model.hpp" // vdbconf_model
28 
29 #include <klib/text.h> /* string_cmp */
30 #include <klib/vector.h> /* Vector */
31 #include <klib/rc.h>
32 #include <klib/guid.h>
33 
34 #include <kfg/kfg-priv.h>
35 
36 #include <cstring> // memset
37 
38 #include <climits> /* PATH_MAX */
39 #include <stdexcept>
40 
41 #ifndef PATH_MAX
42 #define PATH_MAX 4096
43 #endif
44 
45 using namespace std;
46 
47 const int32_t vdbconf_model::kPublicRepoId = -1;
48 const int32_t vdbconf_model::kInvalidRepoId = -2;
49 
50 // error reporting for KConfig_Get/KConfigSet calls: ignore NotFound, throw otherwise
51 static
52 void
HandleRC(rc_t rc,const char * call)53 HandleRC( rc_t rc, const char * call )
54 {
55     if ( rc != 0 && GetRCState ( rc ) != rcNotFound )
56     {
57         throw logic_error ( string ( "vdbconf_model: " ) + call + " failed" );
58     }
59 }
60 
61 #define MODEL_THROW_ON_RC( call ) HandleRC ( call, #call )
62 
vdbconf_model(CKConfig & config)63 vdbconf_model::vdbconf_model( CKConfig & config )
64     : _config( config )
65     , _dir( NULL )
66     , _mgr( NULL )
67     , _vfs_mgr( NULL )
68 {
69     rc_t rc = KDirectoryNativeDir(&_dir);
70     if ( rc != 0 ) throw rc;
71 
72     rc = KConfigMakeRepositoryMgrRead( _config.Get(), &_mgr );
73     if ( rc != 0 ) throw rc;
74 
75     rc = VFSManagerMake ( &_vfs_mgr );
76 }
77 
~vdbconf_model(void)78 vdbconf_model::~vdbconf_model( void )
79 {
80     KRepositoryMgrRelease(_mgr);
81     _mgr = NULL;
82 
83     KDirectoryRelease(_dir);
84     _dir = NULL;
85 
86     VFSManagerRelease ( _vfs_mgr );
87     _vfs_mgr = NULL;
88 }
89 
commit(void)90 bool vdbconf_model::commit( void )
91 {
92     bool x = _config.Commit() == 0;
93     if (x)
94         reload();
95     return x;
96 }
97 
reload(void)98 void vdbconf_model::reload( void )
99 {
100     _config.Reload();
101 }
102 
native_to_internal(const std::string & s) const103 std::string vdbconf_model::native_to_internal( const std::string &s ) const
104 {
105     std::string res = "";
106 
107     VPath * temp_v_path;
108     rc_t rc = VFSManagerMakeSysPath ( _vfs_mgr, &temp_v_path, s.c_str() );
109     if ( rc == 0 )
110     {
111         size_t written;
112         char buffer[ PATH_MAX ];
113         rc = VPathReadPath ( temp_v_path, buffer, sizeof buffer, &written );
114         if ( rc == 0 ) {
115             char resolved [ PATH_MAX ] = "";
116             rc_t rc = KDirectoryResolvePath
117                 ( _dir, true, resolved, sizeof resolved, buffer );
118             if ( rc == 0 ) {
119                 if ( string_cmp ( buffer, written, resolved,
120                             string_measure ( resolved, NULL ), PATH_MAX ) != 0 )
121                 {   // make sure the path is canonic
122                     res = resolved;
123                 }
124                 else {
125                     res.assign( buffer, written );
126                 }
127             }
128         }
129         VPathRelease ( temp_v_path );
130     }
131 
132     return res;
133 }
134 
internal_to_native(const std::string & s) const135 std::string vdbconf_model::internal_to_native( const std::string &s ) const
136 {
137     std::string res = "";
138     VPath * temp_v_path;
139     rc_t rc = VFSManagerMakePath ( _vfs_mgr, &temp_v_path, "%s", s.c_str() );
140     if ( rc == 0 )
141     {
142         size_t written;
143         char buffer[ PATH_MAX ];
144         rc = VPathReadSysPath ( temp_v_path, buffer, sizeof buffer, &written );
145         if ( rc == 0 )
146             res.assign( buffer, written );
147         VPathRelease ( temp_v_path );
148     }
149     return res;
150 }
151 
is_http_proxy_enabled(void) const152 bool vdbconf_model::is_http_proxy_enabled( void ) const
153 {
154     bool enabled = true;
155     KConfig_Get_Http_Proxy_Enabled(_config.Get(), &enabled, true);
156     if ( enabled )
157     {
158         std::string path = get_http_proxy_path();
159         if ( path.empty() ) enabled = false;
160     }
161     return enabled;
162 }
163 
set_http_proxy_enabled(bool enabled)164 void vdbconf_model::set_http_proxy_enabled( bool enabled )
165 {
166     KConfig_Set_Http_Proxy_Enabled(_config.Get(), enabled);
167     _config.Updated();
168 }
169 
get_http_proxy_path(void) const170 std::string vdbconf_model::get_http_proxy_path( void ) const
171 {
172     char buffer[ PATH_MAX ] = "";
173     rc_t rc = KConfig_Get_Http_Proxy_Path(_config.Get(), buffer, sizeof buffer, NULL);
174     if (rc == 0) {
175         return buffer;
176     }
177     else {
178         return "";
179     }
180 }
181 
set_http_proxy_path(const std::string & path)182 void vdbconf_model::set_http_proxy_path(const std::string &path)
183 {
184     KConfig_Set_Http_Proxy_Path(_config.Get(), path.c_str());
185     _config.Updated();
186 }
187 
has_http_proxy_env_higher_priority(void) const188 bool vdbconf_model::has_http_proxy_env_higher_priority( void ) const
189 {
190     bool enabled = false;
191     KConfig_Has_Http_Proxy_Env_Higher_Priority(_config.Get(), &enabled);
192     return enabled;
193 }
set_http_proxy_env_higher_priority(bool value)194 void vdbconf_model::set_http_proxy_env_higher_priority( bool value )
195 {
196     KConfig_Set_Http_Proxy_Env_Higher_Priority(_config.Get(), value);
197     _config.Updated();
198 }
199 
is_remote_enabled(void) const200 bool vdbconf_model::is_remote_enabled( void ) const
201 {
202     bool res = false;
203 
204     rc_t rc = KConfig_Get_Remote_Access_Enabled( _config.Get(), &res );
205     if (rc == 0) {
206         return res;
207     }
208 
209     KConfig_Get_Remote_Main_Cgi_Access_Enabled( _config.Get(), &res );
210     if (!res) {
211         return res;
212     }
213 
214     KConfig_Get_Remote_Aux_Ncbi_Access_Enabled( _config.Get(), &res );
215 
216     return res;
217 }
218 
set_remote_enabled(bool enabled)219 void vdbconf_model::set_remote_enabled( bool enabled )
220 {
221     KConfig_Set_Remote_Access_Enabled( _config.Get(), enabled );
222     _config.Updated();
223 }
224 
does_site_repo_exist(void) const225 bool vdbconf_model::does_site_repo_exist( void ) const
226 {
227     KRepositoryVector repositories;
228     memset( &repositories, 0, sizeof repositories );
229     rc_t rc = KRepositoryMgrSiteRepositories( _mgr, &repositories );
230     bool res = ( ( rc == 0 ) && ( VectorLength( &repositories ) > 0 ) );
231     KRepositoryVectorWhack( &repositories );
232     return res;
233 }
234 
is_site_enabled(void) const235 bool vdbconf_model::is_site_enabled( void ) const
236 {
237     bool res = false;
238     KConfig_Get_Site_Access_Enabled( _config.Get(), &res );
239     return res;
240 }
set_site_enabled(bool enabled)241 void vdbconf_model::set_site_enabled( bool enabled )
242 {
243     if ( does_site_repo_exist() )
244     {
245         KConfig_Set_Site_Access_Enabled( _config.Get(), enabled );
246         _config.Updated();
247     }
248 }
249 
allow_all_certs(void) const250 bool vdbconf_model::allow_all_certs( void ) const
251 {
252     bool res = false;
253     KConfig_Get_Allow_All_Certs( _config.Get(), &res );
254     return res;
255 }
set_allow_all_certs(bool enabled)256 void vdbconf_model::set_allow_all_certs( bool enabled )
257 {
258     KConfig_Set_Allow_All_Certs( _config.Get(), enabled );
259     _config.Updated();
260 }
261 
262 /* THIS IS NEW AND NOT YET IMPLEMENTED IN CONFIG: global cache on/off !!! */
is_global_cache_enabled(void) const263 bool vdbconf_model::is_global_cache_enabled( void ) const
264 {
265     bool res = true;
266     bool is_disabled;
267     rc_t rc = KConfigReadBool ( _config.Get(), "/repository/user/cache-disabled", &is_disabled );
268     if ( rc == 0 )
269         res = !is_disabled;
270     return res;
271 }
272 
set_global_cache_enabled(bool enabled)273 void vdbconf_model::set_global_cache_enabled( bool enabled )
274 {
275     KConfigWriteBool( _config.Get(), "/repository/user/cache-disabled", !enabled );
276     _config.Updated();
277 }
278 
is_user_cache_enabled(void) const279 bool vdbconf_model::is_user_cache_enabled( void ) const
280 {
281     bool res = false;
282     KConfig_Get_User_Public_Cached( _config.Get(), &res );
283     return res;
284 }
set_user_cache_enabled(bool enabled)285 void vdbconf_model::set_user_cache_enabled( bool enabled )
286 {
287     KConfig_Set_User_Public_Cached( _config.Get(), enabled );
288     _config.Updated();
289 }
290 
get_repo_count(void) const291 uint32_t vdbconf_model::get_repo_count( void ) const
292 {
293     uint32_t res = 0;
294     KConfigGetProtectedRepositoryCount( _config.Get(), &res );
295     return res;
296 }
297 
get_repo_id(const string & repo_name) const298 int32_t vdbconf_model::get_repo_id( const string & repo_name ) const
299 {
300     if ( repo_name == "public" )
301         return kPublicRepoId;
302 
303     uint32_t id = 0;
304     rc_t rc = KConfigGetProtectedRepositoryIdByName( _config.Get(), repo_name.c_str(), &id );
305     if ( rc != 0 )
306         return kInvalidRepoId;
307     else
308         return id;
309 }
310 
311 
get_repo_name(uint32_t id) const312 std::string vdbconf_model::get_repo_name( uint32_t id ) const
313 {
314     std::string res = "";
315     size_t written;
316     char buffer[ 1024 ];
317     rc_t rc = KConfigGetProtectedRepositoryName( _config.Get(), id, buffer, sizeof buffer, &written );
318     if ( rc == 0 )
319         res.assign( buffer, written );
320     return res;
321 }
322 
323 
get_repo_description(const string & repo_name) const324 std::string vdbconf_model::get_repo_description(const string &repo_name) const
325 {
326     size_t written = 0;
327     char buffer[ 1024 ];
328     rc_t rc = KConfigGetProtectedRepositoryDescriptionByName( _config.Get(),
329         repo_name.c_str(), buffer, sizeof buffer, &written );
330     if ( rc == 0 )
331         return string( buffer, written );
332     else
333         return "";
334 }
335 
is_protected_repo_cached(uint32_t id) const336 bool vdbconf_model::is_protected_repo_cached( uint32_t id ) const
337 {
338     bool res = true;
339     KConfigGetProtectedRepositoryCachedById( _config.Get(), id, &res );
340     return res;
341 }
342 
set_protected_repo_cached(uint32_t id,bool enabled)343 void vdbconf_model::set_protected_repo_cached( uint32_t id, bool enabled )
344 {
345     KConfigSetProtectedRepositoryCachedById( _config.Get(), id, enabled );
346     _config.Updated();
347 }
348 
does_repo_exist(const char * repo_name)349 bool vdbconf_model::does_repo_exist( const char * repo_name )
350 {
351     bool res = false;
352     KConfigDoesProtectedRepositoryExist( _config.Get(), repo_name, &res );
353     return res;
354 }
355 
get_repo_location(uint32_t id) const356 std::string vdbconf_model::get_repo_location( uint32_t id ) const
357 {
358     std::string res = "";
359     size_t written;
360     char buffer[ PATH_MAX ];
361     rc_t rc = KConfigGetProtectedRepositoryPathById( _config.Get(), id, buffer, sizeof buffer, &written );
362     if ( rc == 0 )
363     {
364         res.assign( buffer, written );
365         res = internal_to_native( res );
366     }
367     return res;
368 }
369 
370 
get_public_location(void) const371 std::string vdbconf_model::get_public_location( void ) const
372 {
373     std::string res = "";
374     size_t written;
375     char buffer[ PATH_MAX ];
376     rc_t rc = KConfig_Get_User_Public_Cache_Location( _config.Get(), buffer, sizeof buffer, &written );
377     if ( rc == 0 )
378     {
379         res.assign( buffer, written );
380         res = internal_to_native( res );
381     }
382     return res;
383 }
384 
385 
get_current_dir(void) const386 std::string vdbconf_model::get_current_dir( void ) const
387 {
388     std::string res = "./";
389     char buffer[ PATH_MAX ];
390     rc_t rc = KDirectoryResolvePath ( _dir, true, buffer, sizeof buffer, "./" );
391     if ( rc == 0 )
392     {
393         res.assign( buffer );
394         res = internal_to_native( res );
395     }
396     return res;
397 }
398 
399 
get_home_dir(void) const400 std::string vdbconf_model::get_home_dir( void ) const
401 {
402     std::string res = "";
403     size_t written;
404     char buffer[ PATH_MAX ];
405     rc_t rc = KConfig_Get_Home( _config.Get(), buffer, sizeof buffer, &written );
406     if ( rc == 0 )
407     {
408         res.assign( buffer, written );
409         res = internal_to_native( res );
410     }
411     return res;
412 }
413 
414 
get_user_default_dir(void) const415 std::string vdbconf_model::get_user_default_dir( void ) const
416 {
417     std::string res = "";
418     size_t written;
419     char buffer[ PATH_MAX ];
420     rc_t rc = KConfig_Get_Default_User_Path( _config.Get(), buffer, sizeof buffer, &written );
421     if ( rc == 0 )
422     {
423         res.assign( buffer, written );
424         res = internal_to_native( res );
425     }
426     return res;
427 }
428 
set_user_default_dir(const char * new_default_dir)429 void vdbconf_model::set_user_default_dir( const char * new_default_dir )
430 {
431     std::string tmp( new_default_dir );
432     tmp = native_to_internal( tmp );
433     KConfig_Set_Default_User_Path( _config.Get(), tmp.c_str() );
434     _config.Updated();
435 }
436 
get_ngc_root(std::string & base,const KNgcObj * ngc) const437 std::string vdbconf_model::get_ngc_root( std::string &base, const KNgcObj * ngc ) const
438 {
439     std::string res = "";
440     size_t written;
441     char buffer[ PATH_MAX ];
442     rc_t rc = KNgcObjGetProjectName ( ngc, buffer, sizeof buffer, &written );
443     if ( rc == 0 )
444     {
445         res = native_to_internal( base ) + '/' + buffer;
446         res = internal_to_native( res );
447     }
448     return res;
449 }
450 
s_IsEmpty(const KDirectory * dir,uint32_t type,const char * name,void * data)451 static rc_t CC s_IsEmpty( const KDirectory * dir, uint32_t type, const char * name, void * data )
452 {
453     if ( ( type & ~kptAlias) != kptDir )
454         return 1;
455     else
456         return 0;
457 }
458 
459 // repoId == kPublicRepoId is for the public repository
x_ChangeRepoLocation(const string & native_newPath,bool reuseNew,int32_t repoId,bool flushOld)460 ESetRootState vdbconf_model::x_ChangeRepoLocation( const string &native_newPath,
461     bool reuseNew, int32_t repoId, bool flushOld )
462 {
463 /*rc_t CC KDirectoryResolvePath_v1 ( const KDirectory_v1 *self, bool absolute,
464     char *resolved, size_t rsize, const char *path, ... )
465     resolve ~
466     and ~user */
467     // old root path
468 
469     if ( native_newPath.size() == 0 )
470         return eSetRootState_NewPathEmpty;
471 
472     std::string newPath = native_to_internal( native_newPath );
473 
474     string oldPath;
475 
476     if ( repoId != kInvalidRepoId )
477     {
478         if ( repoId == kPublicRepoId )
479             oldPath = get_public_location();
480         else if ( repoId >= 0 )
481             oldPath = get_repo_location( repoId );
482         else
483             return eSetRootState_Error;
484 
485         if ( oldPath.size() == newPath.size() )
486         {
487             // make sure new path is different from the old one
488             if ( oldPath == newPath )
489                 return eSetRootState_NotChanged;
490         }
491 
492         // old root path should not be empty - just ignore it now
493         if ( oldPath.size() > 0 )
494         {
495             KPathType type = KDirectoryPathType( _dir, oldPath.c_str() );
496             if ( ( type & ~kptAlias ) == kptDir )
497             {
498                 rc_t rc = KDirectoryVisit ( _dir, true, s_IsEmpty, NULL, oldPath.c_str() );
499                 if ( rc != 0 && !flushOld )
500                 {
501                     // warn if the old repo is not empty and flush was not asked
502                     return eSetRootState_OldNotEmpty;
503                 }
504             }
505         }
506     }
507 
508     KPathType type = KDirectoryPathType( _dir, newPath.c_str() );
509     uint32_t access = 0775;
510     switch ( type & ~kptAlias )
511     {
512         case kptNotFound :
513             {
514                 // create non existing new repository directory
515                 rc_t rc = KDirectoryCreateDir( _dir, access, (kcmCreate | kcmParents), newPath.c_str() );
516                 if ( rc != 0 )
517                     return eSetRootState_MkdirFail;
518             }
519             break;
520 
521         case kptDir :
522             {
523                 rc_t rc = KDirectoryVisit( _dir, true, s_IsEmpty, NULL, newPath.c_str() );
524                 if ( rc != 0 && !reuseNew )
525                     // warn if the new repo is not empty and resuse was not asked
526                     return eSetRootState_NewDirNotEmpty;
527             }
528             break;
529 
530         // error: new repository exists and it is not a directory
531         default : return eSetRootState_NewNotDir;
532     }
533 
534     // create apps subdirectories
535     const char *apps[] = { "files", "nannot", "refseq", "sra", "wgs", NULL };
536     for ( const char **p = apps; *p; ++p )
537     {
538         KPathType type = KDirectoryPathType( _dir, "%s/%s", newPath.c_str(), *p );
539         switch ( type & ~kptAlias )
540         {
541             case kptNotFound : KDirectoryCreateDir( _dir, access, kcmCreate, "%s/%s", newPath.c_str(), *p );
542             case kptDir : break;
543             default : return eSetRootState_Error;
544         }
545     }
546 
547     // update repository root configiration
548     if ( repoId == kPublicRepoId )
549         KConfig_Set_User_Public_Cache_Location( _config.Get(), newPath.c_str() );
550     else if ( repoId >= 0 )
551         KConfigSetProtectedRepositoryPathById( _config.Get(), repoId, newPath.c_str() );
552 
553     if ( repoId != kInvalidRepoId )
554     {
555         // flush the old repository
556         for ( const char **p = apps; *p; ++p )
557         {
558             // completely remove all old apps subdirectories
559             KDirectoryRemove( _dir, true, "%s/%s", oldPath.c_str(), *p );
560         }
561         // remove all old repository directory if it is empty now
562         KDirectoryRemove( _dir, false, oldPath.c_str() );
563     }
564 
565     return eSetRootState_OK;
566 }
567 
set_repo_location(uint32_t id,bool flushOld,const string & path,bool reuseNew)568 ESetRootState vdbconf_model::set_repo_location(uint32_t id,
569     bool flushOld, const string &path, bool reuseNew)
570 {
571     ESetRootState res = x_ChangeRepoLocation( path, reuseNew, id, flushOld );
572     _config.Updated();
573     return res;
574 }
575 
unset_public_repo_location(void)576 void vdbconf_model::unset_public_repo_location( void )
577 {
578     KConfig_Set_User_Public_Cache_Location( _config.Get(), "" );
579     _config.Updated();
580 }
581 
set_public_location(bool flushOld,string & path,bool reuseNew)582 ESetRootState vdbconf_model::set_public_location(
583     bool flushOld, string &path, bool reuseNew)
584 {
585     ESetRootState res = x_ChangeRepoLocation( path, reuseNew, kPublicRepoId, flushOld );
586     _config.Updated();
587     return res;
588 }
589 
change_repo_location(bool flushOld,const string & newPath,bool reuseNew,int32_t repoId)590 ESetRootState vdbconf_model::change_repo_location(bool flushOld,
591     const string &newPath, bool reuseNew, int32_t repoId)
592 {
593     ESetRootState res = x_ChangeRepoLocation( newPath, reuseNew, repoId, flushOld );
594     _config.Updated();
595     return res;
596 }
597 
prepare_repo_directory(const string & newPath,bool reuseNew)598 ESetRootState vdbconf_model::prepare_repo_directory
599     (const string &newPath, bool reuseNew)
600 {
601     ESetRootState res = x_ChangeRepoLocation( newPath, reuseNew, kInvalidRepoId );
602     _config.Updated();
603     return res;
604 }
605 
is_user_public_enabled(void) const606 bool vdbconf_model::is_user_public_enabled( void ) const
607 {
608     bool res = true;
609     KConfig_Get_User_Public_Enabled( _config.Get(), &res );
610     return res;
611 }
set_user_public_enabled(bool enabled)612 void vdbconf_model::set_user_public_enabled( bool enabled )
613 {
614     KConfig_Set_User_Public_Enabled( _config.Get(), enabled );
615     _config.Updated();
616 }
617 
is_user_public_cached(void) const618 bool vdbconf_model::is_user_public_cached( void ) const
619 {
620     bool res = true;
621     KConfig_Get_User_Public_Cached( _config.Get(), &res );
622     return res;
623 }
624 
set_user_public_cached(bool enabled)625 void vdbconf_model::set_user_public_cached( bool enabled )
626 {
627     KConfig_Set_User_Public_Cached( _config.Get(), enabled );
628     _config.Updated();
629 }
630 
631 #if TDB
check_locations_unique(KRepositoryVector * nonUniqueRepos,const string & newRootPath)632 bool check_locations_unique(KRepositoryVector *nonUniqueRepos,
633     const string &newRootPath)
634 {
635     assert(nonUniqueRepos);
636     KRepositoryVectorWhack(nonUniqueRepos);
637 
638     KRepositoryVector repositories;
639     memset(&repositories, 0, sizeof repositories);
640     rc_t rc = KRepositoryMgrUserRepositories(_mgr, &repositories);
641     uint32_t len = 0;
642     if (rc == 0) {
643         len = VectorLength(&repositories);
644     }
645     std::map<const string, const KRepository*> roots;
646     typedef std::map<const string, const KRepository*>::const_iterator TCI;
647     if (len > 0) {
648         for (uint32_t i = 0; i < len; ++i) {
649             const KRepository *repo = static_cast<const KRepository*>
650                 (VectorGet(&repositories, i));
651             if (repo != NULL) {
652                 char buffer[PATH_MAX] = "";
653                 size_t size = 0;
654                 rc = KRepositoryRoot(repo, buffer, sizeof buffer, &size);
655                 if (rc == 0) {
656                     const string root(buffer);
657                     TI it = find(root);
658                     if (it == end()) {
659                         insert(std::pair<const string, const KRepository*>
660                             (root, repo));
661                     }
662                     else {
663                         if (VectorLength(nonUniqueRepos) == 0) {
664                             const KRepository *r = KRepositoryAddRef(repo);
665                             if (r != NULL) {
666               /*ignored rc = */ VectorAppend(repositories, NULL, r);
667                             }
668                         }
669                         const KRepository *found = (*it);
670                         const KRepository *r = KRepositoryAddRef(found);
671                     }
672                 }
673             }
674         }
675     }
676     KRepositoryVectorWhack( &repositories );
677 }
678 #endif
679 
import_ngc(const std::string & native_location,const KNgcObj * ngc,uint32_t permissions,uint32_t * result_flags)680 bool vdbconf_model::import_ngc( const std::string &native_location,
681     const KNgcObj *ngc, uint32_t permissions, uint32_t * result_flags )
682 {
683     bool res = false;
684 
685     KRepositoryMgr * repo_mgr;
686     rc_t rc = KConfigMakeRepositoryMgrUpdate ( _config.Get(), &repo_mgr );
687     if ( rc == 0 )
688     {
689         std::string location = native_to_internal( native_location);
690 
691         rc = KRepositoryMgrImportNgcObj( repo_mgr, ngc,
692             location.c_str(), permissions, result_flags );
693         res = ( rc == 0 );
694         KRepositoryMgrRelease( repo_mgr );
695     }
696 
697     return res;
698 }
699 
get_id_of_ngc_obj(const KNgcObj * ngc,uint32_t * id)700 bool vdbconf_model::get_id_of_ngc_obj( const KNgcObj *ngc, uint32_t * id )
701 {
702     bool res = false;
703     size_t written;
704     char proj_id[ 512 ];
705     rc_t rc = KNgcObjGetProjectName( ngc, proj_id, sizeof proj_id, &written );
706     if ( rc == 0 )
707     {
708         rc = KConfigGetProtectedRepositoryIdByName( _config.Get(), proj_id, id );
709         res = ( rc == 0 );
710     }
711     return res;
712 }
713 
mkdir(const KNgcObj * ngc)714 bool vdbconf_model::mkdir(const KNgcObj *ngc)
715 {
716     uint32_t id = 0;
717     if (!get_id_of_ngc_obj(ngc, &id)) {
718         return false;
719     }
720 
721     const std::string root(get_repo_location(id));
722     if (root.size() == 0) {
723         return false;
724     }
725 
726     if (KDirectoryPathType(_dir, root.c_str()) != kptNotFound) {
727         return false;
728     }
729 
730     return KDirectoryCreateDir(_dir, 0775,
731         kcmCreate | kcmParents, root.c_str()) == 0;
732 }
733 
does_path_exist(std::string & path)734 bool vdbconf_model::does_path_exist( std::string &path )
735 {
736     bool res = false;
737     if ( _dir != NULL )
738     {
739         KPathType type = KDirectoryPathType( _dir, path.c_str() );
740         res = ( ( type & ~kptAlias ) == kptDir );
741     }
742     return res;
743 }
744 
745 
746 
747 bool
does_prefetch_download_to_cache(void) const748 vdbconf_model::does_prefetch_download_to_cache(void) const
749 {
750     bool ret;
751     MODEL_THROW_ON_RC ( KConfig_Get_Prefetch_Download_To_Cache( _config.Get(), & ret) );
752     return ret;
753 }
754 void
set_prefetch_download_to_cache(bool download_to_cache)755 vdbconf_model::set_prefetch_download_to_cache(bool download_to_cache)
756 {
757     MODEL_THROW_ON_RC ( KConfig_Set_Prefetch_Download_To_Cache( _config.Get(), download_to_cache ) );
758     _config.Updated();
759 }
760 
761 bool
does_user_accept_aws_charges(void) const762 vdbconf_model::does_user_accept_aws_charges(void) const
763 {
764     bool ret;
765     MODEL_THROW_ON_RC ( KConfig_Get_User_Accept_Aws_Charges( _config.Get(), & ret) );
766     return ret;
767 }
768 void
set_user_accept_aws_charges(bool accepts_charges)769 vdbconf_model::set_user_accept_aws_charges(bool accepts_charges)
770 {
771     MODEL_THROW_ON_RC ( KConfig_Set_User_Accept_Aws_Charges( _config.Get(), accepts_charges ) );
772     _config.Updated();
773 }
774 
775 bool
does_user_accept_gcp_charges(void) const776 vdbconf_model::does_user_accept_gcp_charges(void) const
777 {
778     bool ret;
779     MODEL_THROW_ON_RC ( KConfig_Get_User_Accept_Gcp_Charges( _config.Get(), & ret) );
780     return ret;
781 }
782 void
set_user_accept_gcp_charges(bool accepts_charges)783 vdbconf_model::set_user_accept_gcp_charges(bool accepts_charges)
784 {
785     MODEL_THROW_ON_RC ( KConfig_Set_User_Accept_Gcp_Charges( _config.Get(), accepts_charges ) );
786     _config.Updated();
787 }
788 
report_cloud_instance_identity(void) const789 bool vdbconf_model::report_cloud_instance_identity( void ) const
790 {
791     bool ret;
792     MODEL_THROW_ON_RC ( KConfig_Get_Report_Cloud_Instance_Identity( _config.Get(), & ret) );
793     return ret;
794 }
set_report_cloud_instance_identity(bool report_identity)795 void vdbconf_model::set_report_cloud_instance_identity( bool report_identity )
796 {
797     MODEL_THROW_ON_RC ( KConfig_Set_Report_Cloud_Instance_Identity( _config.Get(), report_identity ) );
798     _config.Updated();
799 }
800 
801 string
get_temp_cache_location(void) const802 vdbconf_model::get_temp_cache_location(void) const
803 {
804     char buf [ PATH_MAX ];
805     size_t written;
806     MODEL_THROW_ON_RC ( KConfig_Get_Temp_Cache ( _config.Get(), buf, sizeof buf, & written ) );
807     return string ( buf, written );
808 }
809 void
set_temp_cache_location(const std::string & path)810 vdbconf_model::set_temp_cache_location(const std::string & path)
811 {
812     MODEL_THROW_ON_RC ( KConfig_Set_Temp_Cache ( _config.Get(), path . c_str() ) );
813     _config.Updated();
814 }
815 
816 string
get_gcp_credential_file_location(void) const817 vdbconf_model::get_gcp_credential_file_location(void) const
818 {
819     char buf [ PATH_MAX ];
820     size_t written;
821     MODEL_THROW_ON_RC ( KConfig_Get_Gcp_Credential_File ( _config.Get(), buf, sizeof buf, & written ) );
822     return string ( buf, written );
823 }
824 void
set_gcp_credential_file_location(const std::string & path)825 vdbconf_model::set_gcp_credential_file_location(const std::string & path)
826 {
827     MODEL_THROW_ON_RC ( KConfig_Set_Gcp_Credential_File ( _config.Get(), path . c_str() ) );
828     _config.Updated();
829 }
830 
831 string
get_aws_credential_file_location(void) const832 vdbconf_model::get_aws_credential_file_location(void) const
833 {
834     char buf [ PATH_MAX ];
835     size_t written;
836     MODEL_THROW_ON_RC ( KConfig_Get_Aws_Credential_File ( _config.Get(), buf, sizeof buf, & written ) );
837     return string ( buf, written );
838 }
839 void
set_aws_credential_file_location(const std::string & path)840 vdbconf_model::set_aws_credential_file_location(const std::string & path)
841 {
842     MODEL_THROW_ON_RC ( KConfig_Set_Aws_Credential_File ( _config.Get(), path . c_str() ) );
843     _config.Updated();
844 }
845 
846 string
get_aws_profile(void) const847 vdbconf_model::get_aws_profile(void) const
848 {
849     char buf [ PATH_MAX ];
850     size_t written;
851     MODEL_THROW_ON_RC ( KConfig_Get_Aws_Profile ( _config.Get(), buf, sizeof buf, & written ) );
852     return string ( buf, written );
853 }
854 void
set_aws_profile(const std::string & path)855 vdbconf_model::set_aws_profile(const std::string & path)
856 {
857     MODEL_THROW_ON_RC ( KConfig_Set_Aws_Profile ( _config.Get(), path . c_str() ) );
858     _config.Updated();
859 }
860 
get_cache_amount_in_MB(void) const861 uint32_t vdbconf_model::get_cache_amount_in_MB( void ) const
862 {
863     uint32_t value;
864     MODEL_THROW_ON_RC ( KConfig_Get_Cache_Amount ( _config.Get(), &value ) );
865     return value;
866 }
867 
set_cache_amount_in_MB(uint32_t value)868 void vdbconf_model::set_cache_amount_in_MB( uint32_t value )
869 {
870     MODEL_THROW_ON_RC ( KConfig_Set_Cache_Amount ( _config.Get(), value ) );
871     _config.Updated();
872 }
873 
set_defaults(void)874 void vdbconf_model::set_defaults( void )
875 {
876     set_remote_enabled( true );
877     set_global_cache_enabled( true );
878     set_site_enabled( true );
879 
880     set_http_proxy_enabled( false );
881 
882     set_user_accept_aws_charges( false );
883     set_user_accept_gcp_charges( false );
884 
885     std::string dflt_path( "" );
886     set_gcp_credential_file_location( dflt_path );
887     set_aws_credential_file_location( dflt_path );
888 
889     std::string dflt_profile( "default" );
890     set_aws_profile( dflt_profile );
891 }
892 
get_dflt_import_path_start_dir(void)893 std::string vdbconf_model::get_dflt_import_path_start_dir( void )
894 {
895     std::string res = get_user_default_dir();
896     if ( !does_path_exist( res ) )
897         res = get_home_dir();
898     if ( !does_path_exist( res ) )
899         res = get_current_dir();
900     return res;
901 }
902 
get_guid(void) const903 std::string vdbconf_model::get_guid( void ) const
904 {
905     char buf[ 64 ];
906     size_t written = 0;
907     rc_t rc = KConfig_Get_GUID ( _config.Get(), buf, sizeof buf, &written );
908     if ( rc != 0 ) written = 0;
909     return std::string( buf, written );
910 }
911 
check_guid(void)912 void vdbconf_model::check_guid( void )
913 {
914     std::string value = get_guid();
915     if ( value.empty() )
916     {
917         char buf[ 64 ];
918         MODEL_THROW_ON_RC ( KGUIDMake( buf, sizeof buf ) );
919         MODEL_THROW_ON_RC ( KConfig_Set_GUID( _config.Get(), buf ) );
920         _config.Updated();
921         commit();
922     }
923 }
924 
925 /* full-quality related functions */
get_full_quality(void) const926 bool vdbconf_model::get_full_quality( void ) const
927 {
928     bool res = false;
929     MODEL_THROW_ON_RC( KConfig_Get_FullQuality( _config.Get(), &res ) );
930     return res;
931 }
932 
set_full_quality(bool b)933 void vdbconf_model::set_full_quality( bool b )
934 {
935     MODEL_THROW_ON_RC ( KConfig_Set_FullQuality( _config.Get(), b ) );
936     _config.Updated();
937 }
938