1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
/*
* File: configfiles.cpp
*
* Author: Lukas Zeller (luz@synthesis.ch)
*
* Linux Platform adaptor for accessing config files
*
* Copyright (c) 2002-2009 by Synthesis AG (www.synthesis.ch)
*
* 2002-11-18 : luz : created
*
*
*/
#include "sysync.h"
#ifdef ANDROID
#include <unistd.h>
#endif
#include <sys/types.h>
#include <pwd.h>
// determine OS version
static bool getOSVersion(string &aOSVersion)
{
// Obtain OS Version
//%%%% for now
aOSVersion="unknown";
return false;
} // getOSVersion
// determine hardware name
static bool getHardwareName(string &aHardwareName)
{
// Obtain Device name
#ifdef ANDROID
aHardwareName="Android Device";
#else
aHardwareName="Linux PC";
#endif
return true;
} // getHardwareName
/// @brief get platform specific string by ID
/// @return false if string is not available for this platform
/// @param aStringID string selector ID
/// @param aString will receive the requested string
bool getPlatformString(TPlatformStringID aStringID, string &aString)
{
const sInt16 bufsiz=1024;
char buffer[bufsiz];
buffer[0]=0; // terminate for safety
string str;
string aSub;
struct passwd *userInfoP=NULL;
switch (aStringID) {
case pfs_platformvers:
// Platform OS version string
getOSVersion(aString);
break;
case pfs_device_uri:
getLocalDeviceID(aString);
break;
case pfs_device_name:
getHardwareName(aString);
break;
case pfs_loccfg_path:
#ifdef STANDALONE_APP
// default path for local config for XPT standalones is the current dir
aString = ".";
break;
#endif
// for server modules, it is same as the global config path
#ifndef STANDALONE_APP
case pfs_globcfg_path:
// global config directory path
aString = "/etc";
break;
#endif
case pfs_defout_path:
// default output path (formerly: default write path)
#ifdef STANDALONE_APP
// default path for local config for XPT standalones is the current dir
aString = ".";
#else
// for server modules, default log path is /var/log
aString = "/var/log";
#endif
break;
case pfs_temp_path:
// temp path
aString = "/temp";
break;
case pfs_userdir_path:
// user's home dir for user-visible documents and files
userInfoP = getpwuid(getuid());
aString = userInfoP->pw_dir; // home dir
break;
#ifdef APPDATA_SUBDIR
case pfs_appdata_path:
// My specific subdirectory for storing my app data/prefs
userInfoP = getpwuid(getuid());
aString = userInfoP->pw_dir; // user home dir
aSub = APPDATA_SUBDIR;
#ifdef ANDROID
aString += "/data/com.sysync"; // application specific subdir for android
if (!aSub.empty()) aString+= "/"; // slash only if subdir is really there
#else
aString += "/.sysync/"; // application specific subdir
// don't adapt it here to avoid potential problems on other platforms
#endif
aString += aSub;
break;
#endif
/*
case pfs_prefs_path:
// general directory where all applications store data & prefs (for current user)
aString = %%%
break;
*/
/*
case pfs_exedir_path:
exedir:
// path where module file resides
aString = %%%
break;
*/
default:
// unknown ID
return false;
}
// ok
return true;
} // getPlatformString
extern "C" {
#ifndef ANDROID
#include <ctime>
#endif
#include <sys/stat.h>
}
/// @brief update string such that it can be used as target OS directory path
/// (filename can be appended without any separator)
/// @param aPath path to be updated
/// @param aMakeDirs if set, directories along path are created if not existing
/// @return false if directory does not exist or could not be created (when aMakeDirs is set)
bool makeOSDirPath(string &aPath, bool aMakeDirs)
{
// make sure path ends with backslash
string::size_type n=aPath.size();
if (n>=1 && aPath[n-1]!='/')
aPath+='/';
// now make sure path exists if requested
if (aMakeDirs) {
// no slash at the end
string tmppath;
tmppath.assign(aPath,0,aPath.size()-1);
// optimization check if entire path exists
struct stat statinfo;
int rc=stat(aPath.c_str(),&statinfo);
if(rc!=0 || !S_ISDIR(statinfo.st_mode)) {
#ifdef ANDROID
rc = 0; // BFO_INCOMPLETE
#else
rc = errno;
#endif
// path does not exist yet - start from beginning to create it
n=0;
bool knownmissing=false;
// skip first slash for absolute paths
if (aPath[0]=='/') n+=1; // skip
do {
// find first directory in path
n=aPath.find("/",n);
// if no more separators to find, all dirs exist now
if (n==string::npos) break;
tmppath.assign(aPath,0,n);
n+=1; // skip separator
if (!knownmissing) {
// test if this dir exists
rc=stat(tmppath.c_str(),&statinfo);
if(rc!=0 || !S_ISDIR(statinfo.st_mode)) {
#ifdef ANDROID
rc = 0; // BFO_INCOMPLETE
#else
rc = errno;
#endif
knownmissing=true;
}
}
if (knownmissing) {
// create the subdir (might fail if part of path already exists)
if (mkdir(tmppath.c_str(),S_IRWXU)!=0)
return false; // failure to create directory
}
} while(true);
} // path does not exist yet entirely
} // make path existing
return true;
} // makeOSDirPath
// returns timestamp (UTC) of last file modification or 0 if none known
lineartime_t getFileModificationDate(const char *aFileName)
{
struct stat st;
lineartime_t res;
if (stat(aFileName,&st)!=0) res=0;
else {
// stat ok, get modification date
res= ((lineartime_t)st.st_mtime * secondToLinearTimeFactor) + UnixToLineartimeOffset;
}
// return timestamp
return res;
} // getFileModificationDate
#include <netdb.h>
#include <unistd.h>
// get local device URI/name info
bool getLocalDeviceID(string &aURI)
{
char szHostname[100];
struct hostent *pHostEnt=NULL;
string hostName;
// get name of own machine
if (gethostname(szHostname, sizeof(szHostname))!=0) {
hostName="_unknown_";
}
else {
// get host entry
pHostEnt = gethostbyname(szHostname);
// return fully qualified name of machine as ID
if (pHostEnt)
hostName=pHostEnt->h_name; // DNS name of machine
else
hostName=szHostname; // just name of machine
}
// generate URI from name
#ifdef ANDROID
aURI="android:";
#else
aURI="linux:"; // %%% SCTS does not like http:// here, so we take os:xxxx
#endif
// add name of this machine (fully qualified if possible)
aURI+=hostName;
// this is more or less unique
return true;
} // getLocalDeviceID
// write to platform's "console", whatever that is
void PlatformConsolePuts(const char *aText)
{
// generic output
#ifdef ANDROID
__android_log_write( ANDROID_LOG_DEBUG, "ConsolePuts", aText );
#else
puts(aText); // appends newline itself
#endif
} // PlatformConsolePuts
/* eof */
|