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 <vfs/keyring-priv.h>
28 
29 #include <kfg/config.h>
30 
31 #include <klib/text.h>
32 #include <klib/rc.h>
33 #include <klib/log.h>
34 #include <klib/printf.h>
35 
36 #include <kfs/file.h>
37 #include <kfs/directory.h>
38 #include <kfs/lockfile.h>
39 
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <errno.h>
43 #include <stdlib.h>
44 #include <sys/wait.h>
45 
46 #include <stdio.h>
47 
48 #ifndef MAX_PATH
49 #define MAX_PATH 4096
50 #endif
51 
52 const char* KeyRingDefaultDataDir = "~/.ncbi";
53 
54 /*TODO: move to ../keyring.c */
KKeyRingIsServerRunning(const char * dataDir)55 LIB_EXPORT bool CC KKeyRingIsServerRunning(const char* dataDir)
56 {
57     KDirectory* wd;
58     rc_t rc = KDirectoryNativeDir (&wd);
59     if (rc == 0)
60     {
61         char lockFileName[MAX_PATH];
62         if (dataDir == NULL)
63             dataDir = KeyRingDefaultDataDir;
64         rc = string_printf(lockFileName, sizeof(lockFileName)-1, NULL, "%s/keyring_lock", dataDir);
65 
66         if (rc == 0)
67         {
68             KFile* lockedFile;
69             rc = KDirectoryCreateExclusiveAccessFile(wd, &lockedFile, true, 0600, kcmOpen, "%s", lockFileName);
70             if (rc == 0)
71                 KFileRelease(lockedFile);
72         }
73         KDirectoryRelease(wd);
74     }
75     return rc != 0;
76 }
77 
StartKeyRing(const char * dataDir)78 rc_t StartKeyRing(const char* dataDir)
79 {
80     rc_t rc = 0;
81 
82     pid_t child = fork();
83     switch (child)
84     {
85         case 0: /* child */
86         {   /* become the server */
87 
88 /*TODO: calculate based on $(APPPATH) in kfg */
89 const char* KeyRingServerExeName = "/home/boshkina/internal/asm-trace/centos/gcc/stat/x86_64/dbg/bin/keyring-srv";
90 
91             if (dataDir == NULL)
92                 dataDir = "~/.ncbi";
93             LogMsg(klogInfo, "Keyring: execl...");
94 
95             if (execl(KeyRingServerExeName, KeyRingServerExeName, dataDir, NULL) == -1)
96             {   /* TODO: look around:
97                     - same dir as the current executable (kfg/APPPATH)
98                     - current dir
99                     - etc.
100                 */
101             }
102             pLogMsg(klogErr,
103                     "Keyring: execl($(exe)) failed ($(errno)=$(perrno))",
104                     "exe=%s,errno=%d,perrno=%!",
105                     KeyRingServerExeName, errno, errno);
106             exit(1);
107             break;
108         }
109         case -1: /* error */
110         {
111             switch (errno)
112             {
113             case EAGAIN:
114             case ENOMEM:
115                 rc = RC (rcVFS, rcProcess, rcProcess, rcMemory, rcInsufficient);
116                 break;
117             case ENOSYS:
118                 rc = RC (rcVFS, rcProcess, rcProcess, rcInterface, rcUnsupported);
119                 break;
120             default:
121                 rc = RC (rcVFS, rcProcess, rcProcess, rcError, rcUnknown);
122                 break;
123             }
124             break;
125         }
126         default: /* parent */
127             break;
128     }
129 
130     return rc;
131 }
132 
133 #if 0
134 static
135 rc_t GetAppPath(const char* buf, size_t bufsize)
136 {
137     KConfig* kfg;
138     rc_t rc = KConfigMake(&kfg, NULL);
139     if (rc == 0)
140     {
141         const KConfigNode *node;
142         char path[] = "APPPATH";
143         char buf[4096];
144         size_t num_read;
145         rc_t rc2;
146 
147         rc_t rc=KConfigOpenNodeRead(kfg, &node, path, string_measure(path, NULL), "%s", buf);
148         if (rc == 0)
149         {
150             rc = KConfigNodeRead(node, 0, buf, bufsize, &num_read, NULL);
151             rc2 = KConfigNodeRelease(node);
152             if (rc == 0)
153                 rc = r2;
154         }
155         rc2 = KConfigRelease(kfg);
156         if (rc == 0)
157             rc = r2;
158     }
159     return rc;
160 }
161 #endif
162