1/**********************************************************************************
2 * iniOpen
3 *
4 *
5 **************************************************
6 * This code was created by Peter Harvey @ CodeByDesign.
7 * Released under LGPL 28.JAN.99
8 *
9 * Contributions from...
10 * -----------------------------------------------
11 * PAH = Peter Harvey - pharvey@codebydesign.com
12 * -----------------------------------------------
13 *
14 * PAH 06.MAR.99 Can now create file-less INI. Pass NULL for
15 * pszFileName. Then copy a file name into hIni->szFileName
16 * before calling iniCommit.
17 **************************************************/
18
19#include <config.h>
20#include "ini.h"
21
22/*
23 * Changes sent by MQJoe, to avoid limit on number of open file handles
24 */
25
26/***************************************************
27 * Override fstream command to overcome 255 file
28 * handle limit
29 ***************************************************/
30
31#include <fcntl.h>
32#ifdef HAVE_SYS_STAT_H
33#include <sys/stat.h>
34#endif
35#ifdef HAVE_UNISTD_H
36#include <unistd.h>
37#endif
38#include <stdarg.h>
39#include <errno.h>
40
41#if defined( HAVE_VSNPRINTF ) && defined( USE_LL_FIO )
42
43FILE *uo_fopen( const char *filename, const char *mode )
44{
45 int fp;
46 long oMode = 0, pMode = 0;
47
48 pMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
49
50 switch ( mode[0] )
51 {
52 case 'r':
53 oMode = O_RDONLY;
54 break;
55
56 case 'w':
57 oMode = O_RDWR | O_CREAT | O_TRUNC;
58 break;
59
60 case 'o':
61 oMode = O_RDWR | O_CREAT | O_TRUNC;
62 break;
63
64 case 'a':
65 oMode = O_CREAT | O_APPEND | O_WRONLY;
66 break;
67
68 default:
69 return FALSE;
70 }
71
72 fp = open(filename, oMode, pMode );
73
74 return(fp != -1) ? (FILE*)fp : NULL;
75}
76
77int uo_fclose( FILE *stream )
78{
79 close((int)stream);
80 return 0;
81}
82
83char *uo_fgets( char *buffer, int n, FILE *stream )
84{
85 int fp = (int)stream;
86 char ch;
87 int i = 0, c = 0;
88
89 buffer[0] = 0;
90
91 do
92 {
93 c = read(fp, &ch, 1);
94
95 if ( c == 1 )
96 {
97 buffer[i++] = ch;
98
99 if ( ch == '\n' )
100 break;
101 }
102 } while ( c && i < n );
103
104 buffer[i] = 0;
105
106 return(c) ? buffer : NULL;
107}
108
109int uo_vfprintf( FILE *stream, const char *fmt, va_list ap)
110{
111 int fp = (int)stream;
112 long lNeededSize = 256;
113 char* szBuffer = NULL;
114 long lBufSize = 0;
115 int r = 0;
116
117 do
118 {
119 if ( lNeededSize > lBufSize )
120 {
121 if ( szBuffer )
122 free(szBuffer);
123 szBuffer = (char*)malloc(lNeededSize);
124 lBufSize = lNeededSize;
125 }
126
127 lNeededSize = vsnprintf(szBuffer, lBufSize, fmt, ap);
128 lNeededSize++;
129 }
130 while ( lNeededSize > lBufSize );
131
132 r = write(fp, szBuffer, (lNeededSize - 1) );
133
134 if ( szBuffer )
135 free(szBuffer);
136
137 return r;
138}
139
140int uo_fprintf( FILE *stream, const char *fmt, ...)
141{
142 int r;
143 va_list ap;
144
145 va_start(ap, fmt);
146
147 r = uo_vfprintf(stream,fmt,ap);
148
149 va_end(ap);
150
151 return r;
152}
153
154#endif
155
156/***************************************************/
157
158#ifdef __OS2__
159
160int iniOpen( HINI *hIni, char *pszFileName, char *cComment, char cLeftBracket, char cRightBracket, char cEqual, int bCreate, int bFileType )
161{
162 FILE *hFile;
163 char szLine[INI_MAX_LINE+1];
164 char szObjectName[INI_MAX_OBJECT_NAME+1];
165 char szPropertyName[INI_MAX_PROPERTY_NAME+1];
166 char szPropertyValue[INI_MAX_PROPERTY_VALUE+1];
167 int nValidFile;
168
169 char *ObjectList;
170 char *PropertyList;
171 char *ValueList;
172 int numberObject;
173 int ObjectNumber;
174 int numberProperty;
175 int PropertyNumber;
176 int nValidProperty;
177 char *tmpObjectName;
178 char *tmpPropertyName;
179 char *tmpProperyValue;
180
181#ifdef __OS2DEBUG__
182 printf("iniOpen entered \n");
183#endif
184
185 /* INIT STATEMENT */
186 *hIni = malloc( sizeof(INI) );
187 if ( pszFileName && pszFileName != STDINFILE )
188 strncpy((*hIni)->szFileName, pszFileName, ODBC_FILENAME_MAX );
189 else if ( pszFileName == STDINFILE )
190 strncpy((*hIni)->szFileName, "stdin", ODBC_FILENAME_MAX );
191 else
192 strncpy((*hIni)->szFileName, "", ODBC_FILENAME_MAX );
193
194 strcpy( (*hIni)->cComment, cComment );
195 (*hIni)->cLeftBracket = cLeftBracket;
196 (*hIni)->cRightBracket = cRightBracket;
197 (*hIni)->cEqual = cEqual;
198 (*hIni)->bChanged = FALSE;
199 (*hIni)->hCurObject = NULL;
200 (*hIni)->hFirstObject = NULL;
201 (*hIni)->hLastObject = NULL;
202 (*hIni)->nObjects = 0;
203 (*hIni)->bReadOnly = 0;
204
205 (*hIni)->iniFileType = bFileType;
206
207
208#ifdef __OS2DEBUG__
209 printf("iniOpen file is mode %d \n", bFileType);
210#endif
211
212 /* OPEN FILE */
213 if ( pszFileName )
214 {
215 if ( pszFileName == STDINFILE )
216 {
217 hFile = stdin;
218 (*hIni)->iniFileType = 0; /* stdin is always text */
219 }
220 else
221 {
222 if ( (*hIni)->iniFileType == 0 )
223 hFile = uo_fopen( pszFileName, "r" );
224 else
225 hFile = (FILE *)iniOS2Open( pszFileName);
226 }
227
228 if ( !hFile )
229 {
230 /*
231 * This could fail because of something other than the file not existing...
232 */
233
234 if ( bCreate == TRUE )
235 {
236 if ( (*hIni)->iniFileType == 0 )
237 hFile = uo_fopen( pszFileName, "w+" );
238 else
239 hFile = (FILE *)iniOS2Open( pszFileName);
240 }
241 }
242
243 if ( !hFile )
244 {
245 free( *hIni );
246 *hIni = NULL;
247 return INI_ERROR;
248 }
249
250 if ( (*hIni)->iniFileType == 1 )
251 {
252
253 nValidFile = INI_ERROR;
254 ObjectList = (char *)iniOS2LoadObjectList( hFile, &numberObject);
255 if ( numberObject > 0 )
256 {
257 nValidFile = INI_SUCCESS;
258
259 ObjectNumber = 0;
260 do
261 {
262 tmpObjectName = (char *)(ObjectList + ObjectNumber);
263 strcpy(szObjectName, tmpObjectName);
264 iniObjectInsert( (*hIni), szObjectName );
265
266
267 PropertyList = (char *)iniOS2LoadPropertyList( hFile, szObjectName, &numberProperty);
268 if ( numberProperty > 0 )
269 {
270
271
272 PropertyNumber = 0;
273 do
274 {
275
276 tmpPropertyName = PropertyList + PropertyNumber;
277 strcpy(szPropertyName, tmpPropertyName);
278 ValueList = (char *)iniOS2Read( hFile, szObjectName, szPropertyName, szPropertyValue);
279 strcpy(szPropertyValue, ValueList);
280 iniPropertyInsert( (*hIni), szPropertyName, szPropertyValue);
281
282 PropertyNumber = PropertyNumber + strlen(szPropertyName) + 1;
283 } while ( PropertyNumber < numberProperty );
284 free(PropertyList);
285 }
286
287 ObjectNumber = ObjectNumber + strlen(szObjectName) + 1;
288 } while ( ObjectNumber < numberObject );
289 free(ObjectList);
290
291 }
292 }
293 else
294 {
295
296 nValidFile = _iniScanUntilObject( *hIni, hFile, szLine );
297 if ( nValidFile == INI_SUCCESS )
298 {
299 char *ptr;
300 do
301 {
302 if ( szLine[0] == cLeftBracket )
303 {
304 _iniObjectRead( (*hIni), szLine, szObjectName );
305 iniObjectInsert( (*hIni), szObjectName );
306 }
307 else if ( (strchr( cComment, szLine[0] ) == NULL ) && !isspace(szLine[0]) )
308 {
309 _iniPropertyRead( (*hIni), szLine, szPropertyName, szPropertyValue );
310 iniPropertyInsert( (*hIni), szPropertyName, szPropertyValue );
311 }
312
313 } while ( (ptr = uo_fgets( szLine, INI_MAX_LINE, hFile )) != NULL );
314 }
315
316 }
317
318 if ( nValidFile == INI_ERROR )
319 {
320 /* INVALID FILE */
321 if ( hFile != NULL )
322 {
323 if ( (*hIni)->iniFileType == 0 )
324 uo_fclose( hFile );
325 else
326 iniOS2Close(hFile);
327 }
328 free( *hIni );
329 *hIni = NULL;
330 return INI_ERROR;
331 }
332
333 /* CLEANUP */
334 if ( hFile != NULL )
335 {
336 if ( (*hIni)->iniFileType == 0 )
337 {
338 uo_fclose( hFile );
339 }
340 else
341 iniOS2Close(hFile);
342 }
343
344 iniObjectFirst( *hIni );
345
346 } /* if file given */
347
348 return INI_SUCCESS;
349}
350
351
352
353
354#else
355int iniOpen( HINI *hIni, char *pszFileName, char *cComment, char cLeftBracket, char cRightBracket, char cEqual, int bCreate )
356{
357 FILE *hFile;
358 char szLine[INI_MAX_LINE+1];
359 char szObjectName[INI_MAX_OBJECT_NAME+1];
360 char szPropertyName[INI_MAX_PROPERTY_NAME+1];
361 char szPropertyValue[INI_MAX_PROPERTY_VALUE+1];
362 int nValidFile;
363
364 /* INIT STATEMENT */
365 *hIni = malloc( sizeof(INI) );
366 if ( pszFileName && pszFileName != STDINFILE )
367 strncpy((*hIni)->szFileName, pszFileName, ODBC_FILENAME_MAX );
368 else if ( pszFileName == STDINFILE )
369 strncpy((*hIni)->szFileName, "stdin", ODBC_FILENAME_MAX );
370 else
371 strncpy((*hIni)->szFileName, "", ODBC_FILENAME_MAX );
372
373 strcpy( (*hIni)->cComment, cComment );
374 (*hIni)->cLeftBracket = cLeftBracket;
375 (*hIni)->cRightBracket = cRightBracket;
376 (*hIni)->cEqual = cEqual;
377 (*hIni)->bChanged = FALSE;
378 (*hIni)->hCurObject = NULL;
379 (*hIni)->hFirstObject = NULL;
380 (*hIni)->hLastObject = NULL;
381 (*hIni)->nObjects = 0;
382 (*hIni)->bReadOnly = 0;
383
384 /* OPEN FILE */
385 if ( pszFileName )
386 {
387 errno = 0;
388 if ( pszFileName == STDINFILE )
389 {
390 hFile = stdin;
391 }
392 else
393 {
394 hFile = uo_fopen( pszFileName, "r" );
395 }
396
397 if ( ( !hFile ) &&
398 ( errno != ENFILE ) && ( errno != EMFILE ) &&
399 ( errno != ENOMEM ) && ( errno != EACCES ) &&
400 ( errno != EFBIG ) && ( errno != EINTR ) &&
401 ( errno != ENOSPC ) && ( errno != EOVERFLOW ) &&
402 ( errno != EWOULDBLOCK ))
403 {
404
405 /*
406 * This could fail because of something other than the file not existing...
407 * so open as w+ just in case
408 */
409
410 if ( bCreate == TRUE )
411 {
412 hFile = uo_fopen( pszFileName, "w+" );
413 }
414 }
415
416 if ( !hFile )
417 {
418 free( *hIni );
419 *hIni = NULL;
420 return INI_ERROR;
421 }
422
423 nValidFile = _iniScanUntilObject( *hIni, hFile, szLine );
424 if ( nValidFile == INI_SUCCESS )
425 {
426 char *ptr;
427 ptr = szLine;
428 do
429 {
430 /*
431 * remove leading spaces
432 */
433 while( isspace( *ptr )) {
434 ptr ++;
435 }
436 if ( *ptr == '\0' ) {
437 continue;
438 }
439 if ( *ptr == cLeftBracket )
440 {
441 _iniObjectRead( (*hIni), ptr, szObjectName );
442 iniObjectInsert( (*hIni), szObjectName );
443 }
444 else if ((strchr( cComment, *ptr ) == NULL ))
445 {
446 _iniPropertyRead( (*hIni), ptr, szPropertyName, szPropertyValue );
447 iniPropertyInsert( (*hIni), szPropertyName, szPropertyValue );
448 }
449
450 } while ( (ptr = uo_fgets( szLine, INI_MAX_LINE, hFile )) != NULL );
451 }
452 else if ( nValidFile == INI_ERROR )
453 {
454 /* INVALID FILE */
455 if ( hFile != NULL )
456 uo_fclose( hFile );
457 free( *hIni );
458 *hIni = NULL;
459 return INI_ERROR;
460 }
461
462 /* CLEANUP */
463 if ( hFile != NULL )
464 uo_fclose( hFile );
465
466 iniObjectFirst( *hIni );
467
468 } /* if file given */
469
470 return INI_SUCCESS;
471}
472
473#endif
474
475