b888914724f99ae8fe328fdb2cb4d67062311e44
[scilab.git] / scilab / modules / ast / src / cpp / system_env / sci_home.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2010 - DIGITEO - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 *
14 */
15
16
17 #include "configvariable.hxx"
18
19 #include "string.hxx"
20 #include "context.hxx"
21
22 extern "C"
23 {
24 #include "sci_malloc.h"
25 #include "sci_home.h"
26 #include "os_string.h"
27 #include "charEncoding.h"
28 #include "PATH_MAX.h"
29 #include "machine.h"
30 #include "version.h"
31 #include "setenvc.h"
32 #include "getenvc.h"
33 #include "setenvvar.h"
34 #include "getshortpathname.h"
35 #include "sciprint.h"
36 #include "isdir.h"
37 #include "createdirectory.h"
38 #ifndef _MSC_VER
39 #include <sys/stat.h>
40 #endif
41 }
42
43 /*--------------------------------------------------------------------------*/
44 wchar_t* getSCIHOMEW(void)
45 {
46     return os_wcsdup(ConfigVariable::getSCIHOME().c_str());
47 }
48 /*--------------------------------------------------------------------------*/
49 char* getSCIHOME(void)
50 {
51     std::wstring tmpSCIHOME = ConfigVariable::getSCIHOME();
52     if (tmpSCIHOME == L"")
53     {
54         tmpSCIHOME = L"empty_SCIHOME";
55     }
56     return wide_string_to_UTF8(tmpSCIHOME.c_str());
57 }
58 /*--------------------------------------------------------------------------*/
59 void setSCIHOME(const char* _sci_home)
60 {
61     wchar_t* pstTemp = to_wide_string(_sci_home);
62     setSCIHOMEW(pstTemp);
63     FREE(pstTemp);
64 }
65 /*--------------------------------------------------------------------------*/
66 void setSCIHOMEW(const wchar_t* _sci_home)
67 {
68     //add SCI value in context as variable
69     types::String *pS = new types::String(_sci_home);
70     symbol::Context::getInstance()->put(symbol::Symbol(L"SCIHOME"), pS);
71
72     std::wstring sci_home(_sci_home);
73     ConfigVariable::setSCIHOME(sci_home);
74 }
75
76 /*--------------------------------------------------------------------------*/
77 wchar_t* computeSCIHOMEW(void)
78 {
79     char* pstTemp = computeSCIHOME();
80     wchar_t* pstReturn = to_wide_string(pstTemp);
81     FREE(pstTemp);
82     return pstReturn;
83 }
84 /*--------------------------------------------------------------------------*/
85 #ifdef _MSC_VER
86 char* computeSCIHOME(void)
87 {
88 #define BASEDIR "Scilab"
89     int ierr = 0;
90     int buflen = PATH_MAX;
91     int iflag = 0;
92
93     char USERPATHSCILAB[PATH_MAX];
94     char SCIHOMEPATH[PATH_MAX * 2];
95     char* SHORTUSERHOMESYSTEM = NULL;
96
97     char USERHOMESYSTEM[PATH_MAX];
98
99     BOOL bConverted = FALSE;
100
101     getenvc(&ierr, "APPDATA", USERHOMESYSTEM, &buflen, &iflag);
102
103     /* if APPDATA not found we try with USERPROFILE */
104     if (ierr)
105     {
106         getenvc(&ierr, "USERPROFILE", USERHOMESYSTEM, &buflen, &iflag);
107     }
108
109     /* convert long path to short path format : remove some special characters */
110     SHORTUSERHOMESYSTEM = getshortpathname(USERHOMESYSTEM, &bConverted);
111     if (SHORTUSERHOMESYSTEM)
112     {
113         if (!isdir(SHORTUSERHOMESYSTEM))
114         {
115             /* last chance, we try to get default all users profile */
116             getenvc(&ierr, "ALLUSERSPROFILE", USERHOMESYSTEM, &buflen, &iflag);
117             if (ierr)
118             {
119                 delete []SHORTUSERHOMESYSTEM;
120                 return NULL;
121             }
122
123             /* convert long path to short path format : remove some special characters */
124             SHORTUSERHOMESYSTEM = getshortpathname(USERHOMESYSTEM, &bConverted);
125
126             if ((!SHORTUSERHOMESYSTEM) || !isdir(SHORTUSERHOMESYSTEM))
127             {
128                 if (SHORTUSERHOMESYSTEM)
129                 {
130                     delete []SHORTUSERHOMESYSTEM;
131                 }
132                 return NULL;
133             }
134         }
135     }
136     else
137     {
138         if (SHORTUSERHOMESYSTEM)
139         {
140             delete []SHORTUSERHOMESYSTEM;
141         }
142         return NULL;
143     }
144
145     /* checks that directory exists */
146     os_strcpy(USERHOMESYSTEM, SHORTUSERHOMESYSTEM);
147     if (SHORTUSERHOMESYSTEM)
148     {
149         delete []SHORTUSERHOMESYSTEM;
150     }
151
152     /* Set SCIHOME environment variable */
153     os_sprintf(USERPATHSCILAB, "%s%s%s", USERHOMESYSTEM, DIR_SEPARATOR, BASEDIR);
154     os_sprintf(SCIHOMEPATH, "%s%s%s", USERPATHSCILAB, DIR_SEPARATOR, SCI_VERSION_STRING);
155
156     /* creates directory if it does not exists */
157     if (!isdir(SCIHOMEPATH))
158     {
159         if (!isdir(USERPATHSCILAB))
160         {
161             createdirectory(USERPATHSCILAB);
162         }
163
164         if (createdirectory(SCIHOMEPATH))
165         {
166
167             return os_strdup(SCIHOMEPATH);
168         }
169     }
170     else
171     {
172         return os_strdup(SCIHOMEPATH);
173     }
174
175     return NULL;
176 }
177 #else
178 char* computeSCIHOME(void)
179 {
180 #define BASEDIR ".Scilab"
181     int ierr   = 0;
182     int buflen = PATH_MAX;
183     int iflag  = 0;
184     char USERPATHSCILAB[PATH_MAX];
185     char USERHOMESYSTEM[PATH_MAX];
186     char SCIHOMEPATH[PATH_MAX * 2];
187     char HOME[] = "HOME";
188
189     getenvc(&ierr, HOME, USERHOMESYSTEM, &buflen, &iflag);
190     if (ierr)
191     {
192         return NULL;
193     }
194
195     /* Set SCIHOME environment variable */
196     sprintf(USERPATHSCILAB, "%s%s%s", USERHOMESYSTEM, DIR_SEPARATOR, BASEDIR);
197     sprintf(SCIHOMEPATH, "%s%s%s", USERPATHSCILAB, DIR_SEPARATOR, SCI_VERSION_STRING);
198
199     /* creates directory if it does not exists */
200     if (!isdir(SCIHOMEPATH))
201     {
202         if (!isdir(USERPATHSCILAB))
203         {
204             createdirectory(USERPATHSCILAB);
205         }
206
207         if (createdirectory(SCIHOMEPATH))
208         {
209             return os_strdup(SCIHOMEPATH);
210         }
211     }
212     else
213     {
214         return os_strdup(SCIHOMEPATH);
215     }
216
217     return NULL;
218 }
219 #endif
220
221 /*--------------------------------------------------------------------------*/
222 char* getenvSCIHOME(void)
223 {
224     int ierr, iflag = 0;
225     int lbuf = PATH_MAX;
226     char *SciHome = new char[PATH_MAX];
227
228     if (SciHome)
229     {
230         getenvc(&ierr, "SCIHOME", SciHome, &lbuf, &iflag);
231
232         if (ierr == 1)
233         {
234             delete[] SciHome;
235             return NULL;
236         }
237     }
238     return SciHome;
239 }
240 /*--------------------------------------------------------------------------*/
241 wchar_t* getenvSCIHOMEW(void)
242 {
243     char *SciHome = getenvSCIHOME();
244     wchar_t* pstTemp = to_wide_string(SciHome);
245     delete[] SciHome;
246     return pstTemp;
247 }
248 /*--------------------------------------------------------------------------*/
249 void putenvSCIHOMEW(const wchar_t* _sci_home)
250 {
251     char* pstTemp = wide_string_to_UTF8(_sci_home);
252     putenvSCIHOME(pstTemp);
253     FREE(pstTemp);
254     return;
255 }
256
257 void putenvSCIHOME(const char* _sci_home)
258 {
259     char *ShortPath = NULL;
260     char *CopyOfDefaultPath = NULL;
261
262     /* to be sure that it's unix 8.3 format */
263     /* c:/progra~1/scilab-5.0 */
264     BOOL bConvertOK = FALSE;
265     ShortPath = getshortpathname(_sci_home, &bConvertOK);
266
267     CopyOfDefaultPath = new char[strlen(_sci_home) + 1];
268     AntislashToSlash(ShortPath, CopyOfDefaultPath);
269
270     setenvc("SCIHOME", ShortPath);
271
272     delete[] CopyOfDefaultPath;
273     FREE(ShortPath);
274 }
275 /*--------------------------------------------------------------------------*/
276 static bool createDirectoryRecursively(std::wstring path)
277 {
278 #ifdef _MSC_VER
279     size_t pos = 0;
280     do
281     {
282         pos = path.find_first_of(L"\\/", pos + 1);
283         if (CreateDirectoryW(path.substr(0, pos).c_str(), NULL) == FALSE)
284         {
285             DWORD d = GetLastError();
286             if (d == ERROR_PATH_NOT_FOUND)
287             {
288                 return false;
289             }
290         }
291     } while (pos != std::string::npos);
292
293 #else
294     char* file_path = wide_string_to_UTF8(path.data());
295
296     char* p = NULL;
297     for (p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/'))
298     {
299         *p = '\0';
300         if (mkdir(file_path, 777) == -1)
301         {
302             if (errno != EEXIST)
303             {
304                 *p = '/';
305                 FREE(file_path);
306                 return false;
307             }
308         }
309         *p = '/';
310     }
311
312     FREE(file_path);
313 #endif
314     return true;
315 }
316 /*--------------------------------------------------------------------------*/
317 void defineSCIHOME()
318 {
319     wchar_t* sci_home = getSCIHOMEW();
320     if (wcscmp(sci_home, L"") == 0)
321     {
322         sci_home = computeSCIHOMEW();
323     }
324     else
325     {
326         if (createDirectoryRecursively(sci_home) == false)
327         {
328             sciprint("Unable to create SCIHOME in `%ls`.\n", sci_home);
329             sciprint("Back to normal behaviour.\n");
330             sci_home = computeSCIHOMEW();
331         }
332     }
333
334     setSCIHOMEW(sci_home);
335     putenvSCIHOMEW(sci_home);
336     FREE(sci_home);
337 }