1 /********************************************************************************
2 * *
3 * M i s c e l l a n e o u s S y s t e m F u n c t i o n s *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2005,2006 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 *********************************************************************************
22 * $Id: FXSystem.cpp 4937 2019-03-10 19:59:30Z arthurcnorman $ *
23 ********************************************************************************/
24 #include "xincs.h"
25 #include "fxver.h"
26 #include "fxdefs.h"
27 #include "fxascii.h"
28 #include "FXHash.h"
29 #include "FXStream.h"
30 #include "FXString.h"
31 #include "FXIO.h"
32 #include "FXSystem.h"
33 #include "FXStat.h"
34
35
36
37 /*
38 Notes:
39 - A bric-a-brack of various functions we could not place anywhere else.
40 */
41
42
43 #ifndef TIMEFORMAT
44 #define TIMEFORMAT "%m/%d/%Y %H:%M:%S"
45 #endif
46
47
48 using namespace FX;
49
50 /*******************************************************************************/
51
52 namespace FX {
53
54
55 // Return current time
now()56 FXTime FXSystem::now(){
57 return (FXTime)::time(NULL);
58 }
59
60
61 // Convert file time to string
time(FXTime value)62 FXString FXSystem::time(FXTime value){
63 return FXSystem::time(TIMEFORMAT,value);
64 }
65
66
67 // Convert file time to string as per strftime format
time(const FXchar * format,FXTime filetime)68 FXString FXSystem::time(const FXchar *format,FXTime filetime){
69 #ifndef WIN32
70 #if defined(FOX_THREAD_SAFE) && !(defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(__OpenBSD__)
71 time_t tmp=(time_t)FXMAX(filetime,0);
72 struct tm tmresult;
73 FXchar buffer[512];
74 FXint len=strftime(buffer,sizeof(buffer),format,localtime_r(&tmp,&tmresult));
75 return FXString(buffer,len);
76 #else
77 time_t tmp=(time_t)FXMAX(filetime,0);
78 FXchar buffer[512];
79 FXint len=strftime(buffer,sizeof(buffer),format,localtime(&tmp));
80 return FXString(buffer,len);
81 #endif
82 #else
83 time_t tmp=(time_t)FXMAX(filetime,0);
84 FXchar buffer[512];
85 FXint len=strftime(buffer,sizeof(buffer),format,localtime(&tmp));
86 return FXString(buffer,len);
87 #endif
88 }
89
90
91 // Get effective user id
user()92 FXuint FXSystem::user(){
93 #ifndef WIN32
94 return geteuid();
95 #else
96 return 0;
97 #endif
98 }
99
100
101 // Get effective group id
group()102 FXuint FXSystem::group(){
103 #ifndef WIN32
104 return getegid();
105 #else
106 return 0;
107 #endif
108 }
109
110
111 // Return owner name from uid
userName(FXuint uid)112 FXString FXSystem::userName(FXuint uid){
113 FXchar result[64];
114 #ifndef WIN32
115 #if defined(FOX_THREAD_SAFE) && !(defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(__OpenBSD__)
116 struct passwd pwdresult,*pwd;
117 char buffer[1024];
118 if(getpwuid_r(uid,&pwdresult,buffer,sizeof(buffer),&pwd)==0 && pwd) return pwd->pw_name;
119 #else
120 struct passwd *pwd=getpwuid(uid);
121 if(pwd) return pwd->pw_name;
122 #endif
123 #endif
124 sprintf(result,"%u",uid);
125 return result;
126 }
127
128
129 // Return group name from gid
groupName(FXuint gid)130 FXString FXSystem::groupName(FXuint gid){
131 FXchar result[64];
132 #ifndef WIN32
133 #if defined(FOX_THREAD_SAFE) && !(defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(__OpenBSD__)
134 ::group grpresult;
135 ::group *grp;
136 char buffer[1024];
137 if(getgrgid_r(gid,&grpresult,buffer,sizeof(buffer),&grp)==0 && grp) return grp->gr_name;
138 #else
139 ::group *grp=getgrgid(gid);
140 if(grp) return grp->gr_name;
141 #endif
142 #endif
143 sprintf(result,"%u",gid);
144 return result;
145 }
146
147
148 // Get current user name
currentUserName()149 FXString FXSystem::currentUserName(){
150 #ifndef WIN32
151 #if defined(FOX_THREAD_SAFE) && !(defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(__OpenBSD__)
152 struct passwd pwdresult,*pwd;
153 char buffer[1024];
154 if(getpwuid_r(geteuid(),&pwdresult,buffer,sizeof(buffer),&pwd)==0 && pwd) return pwd->pw_name;
155 #else
156 struct passwd *pwd=getpwuid(geteuid());
157 if(pwd) return pwd->pw_name;
158 #endif
159 #else
160 TCHAR buffer[MAXPATHLEN];
161 DWORD size=MAXPATHLEN;
162 if(GetUserName(buffer,&size)) return buffer;
163 #endif
164 return FXString::null;
165 }
166
167
168 // Get current effective group name
currentGroupName()169 FXString FXSystem::currentGroupName(){
170 #ifndef WIN32
171 #if defined(FOX_THREAD_SAFE) && !(defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(__OpenBSD__)
172 ::group grpresult;
173 ::group *grp;
174 char buffer[1024];
175 if(getgrgid_r(getegid(),&grpresult,buffer,sizeof(buffer),&grp)==0 && grp) return grp->gr_name;
176 #else
177 ::group *grp=getgrgid(getegid());
178 if(grp) return grp->gr_name;
179 #endif
180 #endif
181 return FXString::null;
182 }
183
184
185 // Return permissions string
modeString(FXuint mode)186 FXString FXSystem::modeString(FXuint mode){
187 FXchar result[11];
188 result[0]=(mode&FXIO::SymLink) ? 'l' : (mode&FXIO::File) ? '-' : (mode&FXIO::Directory) ? 'd' : (mode&FXIO::Character) ? 'c' : (mode&FXIO::Block) ? 'b' : (mode&FXIO::Fifo) ? 'p' : (mode&FXIO::Socket) ? 's' : '?';
189 result[1]=(mode&FXIO::OwnerRead) ? 'r' : '-';
190 result[2]=(mode&FXIO::OwnerWrite) ? 'w' : '-';
191 result[3]=(mode&FXIO::SetUser) ? 's' : (mode&FXIO::OwnerExec) ? 'x' : '-';
192 result[4]=(mode&FXIO::GroupRead) ? 'r' : '-';
193 result[5]=(mode&FXIO::GroupWrite) ? 'w' : '-';
194 result[6]=(mode&FXIO::SetGroup) ? 's' : (mode&FXIO::GroupExec) ? 'x' : '-';
195 result[7]=(mode&FXIO::OtherRead) ? 'r' : '-';
196 result[8]=(mode&FXIO::OtherWrite) ? 'w' : '-';
197 result[9]=(mode&FXIO::Sticky) ? 't' : (mode&FXIO::OtherExec) ? 'x' : '-';
198 result[10]=0;
199 return result;
200 }
201
202
203 // Return value of environment variable name
getEnvironment(const FXString & name)204 FXString FXSystem::getEnvironment(const FXString& name){
205 if(!name.empty()){
206 #ifndef WIN32
207 return FXString(getenv(name.text()));
208 #else
209 FXchar value[1024];
210 DWORD len=GetEnvironmentVariableA(name.text(),value,1024);
211 return FXString(value,len);
212 #endif
213 }
214 return FXString::null;
215 }
216
217
218 // Change value of environment variable name
setEnvironment(const FXString & name,const FXString & value)219 bool FXSystem::setEnvironment(const FXString& name,const FXString& value){
220 if(!name.empty()){
221 #ifndef WIN32
222 #ifdef __GNU_LIBRARY__
223 if(!value.empty()){
224 return setenv(name.text(),value.text(),TRUE)==0;
225 }
226 unsetenv(name.text());
227 return true;
228 #endif
229 #else
230 if(!value.empty()){
231 return SetEnvironmentVariableA(name.text(),value.text())!=0;
232 }
233 return SetEnvironmentVariableA(name.text(),NULL)!=0;
234 #endif
235 }
236 return false;
237 }
238
239
240 // Get current working directory
getCurrentDirectory()241 FXString FXSystem::getCurrentDirectory(){
242 #ifndef WIN32
243 FXchar buffer[MAXPATHLEN];
244 if(getcwd(buffer,MAXPATHLEN)) return buffer;
245 #else
246 TCHAR buffer[MAXPATHLEN];
247 if(GetCurrentDirectory(MAXPATHLEN,buffer)) return buffer;
248 #endif
249 return FXString::null;
250 }
251
252
253 // Change current directory
setCurrentDirectory(const FXString & path)254 FXbool FXSystem::setCurrentDirectory(const FXString& path){
255 if(!path.empty()){
256 #ifdef WIN32
257 #ifdef UNICODE
258 TCHAR buffer[MAXPATHLEN];
259 utf2ncs(buffer,path.text(),path.length()+1);
260 return SetCurrentDirectory(buffer);
261 #else
262 return SetCurrentDirectory(path.text());
263 #endif
264 #else
265 return chdir(path.text())==0;
266 #endif
267 }
268 return FALSE;
269 }
270
271
272 // Get current drive prefix "a:", if any
273 // This is the same method as used in VC++ CRT.
getCurrentDrive()274 FXString FXSystem::getCurrentDrive(){
275 #ifdef WIN32
276 FXchar buffer[MAXPATHLEN];
277 if(GetCurrentDirectoryA(MAXPATHLEN,buffer) && Ascii::isLetter((FXuchar)buffer[0]) && buffer[1]==':') return FXString(buffer,2);
278 #endif
279 return FXString::null;
280 }
281
282
283 #ifdef WIN32
284
285 // Change current drive prefix "a:"
286 // This is the same method as used in VC++ CRT.
setCurrentDrive(const FXString & prefix)287 FXbool FXSystem::setCurrentDrive(const FXString& prefix){
288 FXchar buffer[3];
289 if(!prefix.empty() && Ascii::isLetter(prefix[0]) && prefix[1]==':'){
290 buffer[0]=prefix[0];
291 buffer[1]=':';
292 buffer[2]='\0';
293 return SetCurrentDirectoryA(buffer);
294 }
295 return FALSE;
296 }
297
298 #else
299
300 // Change current drive prefix "a:"
setCurrentDrive(const FXString &)301 FXbool FXSystem::setCurrentDrive(const FXString&){
302 return TRUE;
303 }
304
305 #endif
306
307
308 // Get executable path
getExecPath()309 FXString FXSystem::getExecPath(){
310 return FXString(getenv("PATH"));
311 }
312
313
314 // Return the home directory for the current user.
getHomeDirectory()315 FXString FXSystem::getHomeDirectory(){
316 return FXSystem::getUserDirectory(FXString::null);
317 }
318
319
320 // Get home directory for a given user
getUserDirectory(const FXString & user)321 FXString FXSystem::getUserDirectory(const FXString& user){
322 #ifndef WIN32
323 #if defined(FOX_THREAD_SAFE) && !(defined(__FreeBSD__) || defined(__DragonFly__)) && !defined(__OpenBSD__)
324 struct passwd pwdresult,*pwd;
325 char buffer[1024];
326 if(user.empty()){
327 const FXchar* str;
328 if((str=getenv("HOME"))!=NULL) return str;
329 if((str=getenv("USER"))!=NULL || (str=getenv("LOGNAME"))!=NULL){
330 if(getpwnam_r(str,&pwdresult,buffer,sizeof(buffer),&pwd)==0 && pwd) return pwd->pw_dir;
331 }
332 if(getpwuid_r(getuid(),&pwdresult,buffer,sizeof(buffer),&pwd)==0 && pwd) return pwd->pw_dir;
333 return PATHSEPSTRING;
334 }
335 if(getpwnam_r(user.text(),&pwdresult,buffer,sizeof(buffer),&pwd)==0 && pwd) return pwd->pw_dir;
336 return PATHSEPSTRING;
337 #else
338 struct passwd *pwd;
339 if(user.empty()){
340 const FXchar* str;
341 if((str=getenv("HOME"))!=NULL) return str;
342 if((str=getenv("USER"))!=NULL || (str=getenv("LOGNAME"))!=NULL){
343 if((pwd=getpwnam(str))!=NULL) return pwd->pw_dir;
344 }
345 if((pwd=getpwuid(getuid()))!=NULL) return pwd->pw_dir;
346 return PATHSEPSTRING;
347 }
348 if((pwd=getpwnam(user.text()))!=NULL) return pwd->pw_dir;
349 return PATHSEPSTRING;
350 #endif
351 #else
352 if(user.empty()){
353 const FXchar *str1,*str2;
354 FXchar home[MAXPATHLEN];
355 DWORD size=MAXPATHLEN;
356 HKEY hKey;
357 LONG result;
358 if((str1=getenv("USERPROFILE"))!=NULL) return str1; // Danikl Hvrchner <dbjh@gmx.net>
359 if((str1=getenv("HOME"))!=NULL) return str1;
360 if((str2=getenv("HOMEPATH"))!=NULL){ // This should be good for WinNT, Win2K according to MSDN
361 if((str1=getenv("HOMEDRIVE"))==NULL) str1="c:";
362 strncpy(home,str1,MAXPATHLEN);
363 strncat(home,str2,MAXPATHLEN);
364 return home;
365 }
366 // FXchar buffer[MAX_PATH]
367 // if(SHGetFolderPath(NULL,CSIDL_PERSONAL|CSIDL_FLAG_CREATE,NULL,O,buffer)==S_OK){
368 // return buffer;
369 // }
370 if(RegOpenKeyExA(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",0,KEY_READ,&hKey)==ERROR_SUCCESS){
371 result=RegQueryValueExA(hKey,"Personal",NULL,NULL,(LPBYTE)home,&size); // Change "Personal" to "Desktop" if you want...
372 RegCloseKey(hKey);
373 if(result==ERROR_SUCCESS) return home;
374 }
375 return "c:" PATHSEPSTRING;
376 }
377 return "c:" PATHSEPSTRING;
378 #endif
379 }
380
381
382 // Return temporary directory.
getTempDirectory()383 FXString FXSystem::getTempDirectory(){
384 #ifndef WIN32
385 const FXchar* dir;
386 if((dir=getenv("TMPDIR"))!=NULL){
387 return FXString(dir);
388 }
389 return FXString("/tmp");
390 #else
391 TCHAR buffer[MAXPATHLEN];
392 DWORD len=GetTempPath(MAXPATHLEN,buffer);
393 if(1<len && ISPATHSEP(buffer[len-1]) && !ISPATHSEP(buffer[len-2])) len--;
394 return FXString(buffer,len);
395 #endif
396 }
397
398
399 // Get DLL name for given base name
dllName(const FXString & name)400 FXString FXSystem::dllName(const FXString& name){
401 #if defined(WIN32)
402 return name+".dll";
403 #elif defined(_HPUX_) || defined(_HPUX_SOURCE)
404 return "lib"+name+".sl";
405 #elif defined(_APPLE_)
406 return "lib"+name+".dylib";
407 #else
408 return "lib"+name+".so";
409 #endif
410 }
411
412
413 }
414
415