2
* GetPrivateProfileString()
4
* approximate implementation of
5
* Windows NT System Services version of GetPrivateProfileString()
6
* probably doesn't handle the NULL key for section name or value key
7
* correctly also, doesn't provide Microsoft backwards compatability
8
* wrt TAB characters in the value string
10
* Microsoft terminates value
11
* at the first TAB, but I couldn't discover what the behavior should
12
* be regarding TABS in quoted strings so, I treat tabs like any other
15
* NO comments following value string separated by a TAB
16
* are allowed (that is an anachronism anyway)
17
* Added code to search for ODBC_INI file in users home directory on
23
#if !defined(WIN32) && !defined(WITH_UNIXODBC) && !defined(WITH_IODBC)
32
#include <sys/types.h>
35
#include "dlg_specific.h"
38
#define TRUE ((BOOL)1)
41
#define FALSE ((BOOL)0)
45
#error "ODBCINSTDIR must be defined to compile this file"
50
* theIniFileName is searched for in:
51
* $HOME/theIniFileName
53
* ODBCINSTDIR/ODBCINST_INI
56
GetPrivateProfileString(const char *theSection, /* section name */
57
const char *theKey, /* search key name */
58
const char *theDefault, /* default value if not
60
char *theReturnBuffer, /* return value stored
62
size_t theReturnBufferLength, /* byte length of return
64
const char *theIniFileName) /* pathname of ini file
76
size_t aReturnLength = 0;
77
BOOL aSectionFound = FALSE;
78
BOOL aKeyFound = FALSE;
80
ptr = (char *) getpwuid(getuid()); /* get user info */
82
if (ptr == NULL || (((struct passwd *) ptr)->pw_dir) == NULL || *(((struct passwd *) ptr)->pw_dir) == '\0')
85
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
88
* If it can't be opened because the paths are too long, then skip it,
89
* don't just truncate the path string... The truncated path might
90
* accidently be an existing file. The default value will be returned
93
if (MAXPGPATH - 1 >= strlen(ptr) + 1 + strlen(theIniFileName))
95
sprintf(buf, "%s/%s", ptr, theIniFileName);
96
aFile = (FILE *) fopen(buf, PG_BINARY_R);
100
* This code makes it so that a file in the users home dir overrides a
101
* the "default" file as passed in
105
aFile = (FILE *) fopen(theIniFileName, PG_BINARY_R);
107
aFile = (FILE *) fopen(ODBCINSTDIR "/" ODBCINST_INI, PG_BINARY_R);
110
aLength = (theDefault == NULL) ? 0 : strlen(theDefault);
112
if (theReturnBufferLength == 0 || theReturnBuffer == NULL)
121
/* no ini file specified, return the default */
122
++aLength; /* room for NULL char */
123
aLength = theReturnBufferLength < aLength ?
124
theReturnBufferLength : aLength;
125
strncpy(theReturnBuffer, theDefault, aLength);
126
theReturnBuffer[aLength - 1] = '\0';
130
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
132
aLineLength = strlen(aLine);
133
/* strip final '\n' */
134
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
135
aLine[aLineLength - 1] = '\0';
138
case ' ': /* blank line */
139
case ';': /* comment line */
143
case '[': /* section marker */
144
if ((aString = strchr(aLine, ']')))
148
while (isspace((unsigned char) *aStart))
150
while (isspace((unsigned char) *aString))
152
*(aString + 1) = '\0';
154
/* accept as matched if NULL key or exact match */
155
if (!theSection || !strcmp(aStart, theSection))
156
aSectionFound = TRUE;
158
aSectionFound = FALSE;
164
/* try to match value keys if in proper section */
167
/* try to match requested key */
168
if ((aString = aValue = strchr(aLine, '=')))
173
/* strip leading blanks in value field */
174
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
176
if (aValue >= aLine + sizeof(aLine))
183
while (isspace((unsigned char) *aStart))
186
/* strip trailing blanks from key */
189
while (--aString >= aStart && *aString == ' ')
193
/* see if key is matched */
194
if (theKey == NULL || !strcmp(theKey, aStart))
196
/* matched -- first, terminate value part */
198
aLength = strlen(aValue);
200
/* remove trailing blanks from aValue if any */
201
aString = aValue + aLength - 1;
203
while (--aString > aValue && *aString == ' ')
209
/* unquote value if quoted */
210
if (aLength >= 2 && aValue[0] == '"' &&
211
aValue[aLength - 1] == '"')
213
/* string quoted with double quotes */
215
aValue[aLength - 1] = '\0';
221
/* single quotes allowed also... */
222
if (aLength >= 2 && aValue[0] == '\'' &&
223
aValue[aLength - 1] == '\'')
225
aValue[aLength - 1] = '\0';
231
/* compute maximum length copyable */
232
aLineLength = (aLength <
233
theReturnBufferLength - aReturnLength) ? aLength :
234
theReturnBufferLength - aReturnLength;
236
/* do the copy to return buffer */
239
strncpy(&theReturnBuffer[aReturnLength],
240
aValue, aLineLength);
241
aReturnLength += aLineLength;
242
if (aReturnLength < theReturnBufferLength)
244
theReturnBuffer[aReturnLength] = '\0';
253
return aReturnLength > 0 ? aReturnLength - 1 : 0;
265
/* key wasn't found return default */
266
++aLength; /* room for NULL char */
267
aLength = theReturnBufferLength < aLength ?
268
theReturnBufferLength : aLength;
269
strncpy(theReturnBuffer, theDefault, aLength);
270
theReturnBuffer[aLength - 1] = '\0';
271
aReturnLength = aLength - 1;
273
return aReturnLength > 0 ? aReturnLength - 1 : 0;
278
WritePrivateProfileString(const char *theSection, /* section name */
279
const char *theKey, /* write key name */
280
const char *theBuffer, /* input buffer */
281
const char *theIniFileName) /* pathname of ini file
290
* Ok. What the hell's the default behaviour for a null input buffer, and null
291
* section name. For now if either are null I ignore the request, until
292
* I find out different.
295
WritePrivateProfileString(char *theSection, /* section name */
296
char *theKey, /* write key name */
297
char *theBuffer, /* input buffer */
298
char *theIniFileName) /* pathname of ini file to
309
size_t aReturnLength = 0;
311
BOOL aSectionFound = FALSE;
312
BOOL keyFound = FALSE;
315
/* If this isn't correct processing we'll change it later */
316
if (theSection == NULL || theKey == NULL || theBuffer == NULL ||
317
theIniFileName == NULL)
320
aLength = strlen(theBuffer);
324
j = strlen(theIniFileName) + 1;
325
ptr = (char *) getpwuid(getuid()); /* get user info */
329
if (MAXPGPATH - 1 < j)
330
theIniFileName[MAXPGPATH - 1] = '\0';
332
sprintf(buf, "%s", theIniFileName);
334
ptr = ((struct passwd *) ptr)->pw_dir; /* get user home dir */
335
if (ptr == NULL || *ptr == '\0')
339
* This doesn't make it so we find an ini file but allows normal
340
* processing to continue further on down. The likelihood is that the
341
* file won't be found and thus the default value will be returned.
343
if (MAXPGPATH - 1 < strlen(ptr) + j)
345
if (MAXPGPATH - 1 < strlen(ptr))
346
ptr[MAXPGPATH - 1] = '\0';
348
theIniFileName[MAXPGPATH - 1 - strlen(ptr)] = '\0';
351
sprintf(buf, "%s/%s", ptr, theIniFileName);
354
* This code makes it so that a file in the users home dir overrides a
355
* the "default" file as passed in
357
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
360
sprintf(buf, "%s", theIniFileName);
361
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
366
aLength = strlen(theBuffer);
369
* We have to search for theKey, because if it already exists we have
370
* to overwrite it. If it doesn't exist we just write a new line to
373
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
375
aLineLength = strlen(aLine);
376
/* strip final '\n' */
377
if (aLineLength > 0 && aLine[aLineLength - 1] == '\n')
378
aLine[aLineLength - 1] = '\0';
381
case ' ': /* blank line */
382
case ';': /* comment line */
386
case '[': /* section marker */
387
if ((aString = strchr(aLine, ']')))
391
/* accept as matched if key exact match */
393
if (!strcmp(aLine + 1, theSection))
394
aSectionFound = TRUE;
399
/* try to match value keys if in proper section */
402
/* try to match requested key */
404
if ((aString = aValue = strchr(aLine, '=')))
409
/* strip leading blanks in value field */
410
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
412
if (aValue >= aLine + sizeof(aLine))
418
/* strip trailing blanks from key */
421
while (--aString >= aLine && *aString == ' ')
425
/* see if key is matched */
426
if (!strcmp(theKey, aLine))
429
/* matched -- first, terminate value part */
431
/* overwrite current value */
432
fseek(aFile, -aLineLength, SEEK_CUR);
433
/* overwrite key and value */
434
sprintf(aLine, "%s = %s\n", theKey, theBuffer);
444
{ /* theKey wasn't in file so */
448
return aReturnLength > 0 ? aReturnLength - 1 : 0;
450
#endif /* NOT_USED */
452
#endif /* not WIN32 */