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