3 Copyright 2003 Oswald Buddenhagen <ossi@kde.org>
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of a copyright holder shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
25 from the copyright holder.
30 * xdm - display manager daemon
31 * Author: Keith Packard, MIT X Consortium
33 * load, save and manipulate ini-style config files
39 #include <sys/types.h>
47 iniLoad( const char *fname
)
53 if ((fd
= open( fname
, O_RDONLY
| O_NONBLOCK
)) < 0) {
54 debug( "cannot open ini-file %\"s: %m", fname
);
57 if (fstat( fd
, &st
) || !S_ISREG( st
.st_mode
)) {
58 logWarn( "Ini-file %\"s is no regular file\n", fname
);
62 if (st
.st_size
>= 0x10000) {
63 logWarn( "Ini-file %\"s is too big\n", fname
);
68 if (!(data
= Malloc( len
+ 2 ))) {
72 if (read( fd
, data
, len
) != len
) {
73 debug( "cannot read ini-file %\"s: %m", fname
);
79 if (data
[len
- 1] != '\n') /* iniEntry() needs this. */
86 iniSave( const char *data
, const char *fname
)
90 if ((fd
= open( fname
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_NONBLOCK
, 0600 )) < 0) {
91 debug( "cannot create ini-file %\"s: %m", fname
);
95 if ((cnt
= write( fd
, data
, len
)) == len
) {
100 debug( "cannot write ini-file %\"s: %m", fname
);
102 debug( "cannot write ini-file %\"s: partial write", fname
);
107 #define apparr(d,s,n) do { memcpy (d, s, n); d += n; } while(0)
108 #define appbyte(d,b) *d++ = b
111 * NOTE: this relies on the last line being \n-terminated - if it is not,
112 * it will read past the end of the buffer!
115 iniEntry( char *data
, const char *section
, const char *key
, const char *value
)
117 char *p
= data
, *secinsert
= 0, *pastinsert
= 0, *cb
, *ce
, *ndata
;
119 int insect
= False
, ll
, sl
, kl
, vl
, len
, nlen
;
123 for (; *p
== ' ' || *p
== '\t'; p
++);
125 /* Empty line, so don't advance insertion point. */
130 for (t
= section
; *++p
== *t
; t
++);
131 insect
= !*t
&& *p
== ']';
133 for (t
= key
; *p
== *t
; t
++, p
++);
134 for (; *p
== ' ' || *p
== '\t'; p
++);
135 if (!*t
&& *p
== '=') {
136 for (p
++; *p
== ' ' || *p
== '\t'; p
++);
138 while (*p
++ != '\n');
142 len
= (ce
- data
) + strlen( ce
);
145 for (ce
--; ce
!= cb
&& (*(ce
- 1) == ' ' || *(ce
- 1) == '\t'); ce
--);
146 if (!strNDup( &p
, cb
, ce
- cb
))
152 while (*p
++ != '\n');
166 sl
= strlen( section
) + 3;
168 ce
= cb
= pastinsert
;
175 kl
= strlen( key
) + 1;
177 vl
= strlen( value
);
178 nlen
= len
- (ce
- cb
) + ll
+ sl
+ kl
+ vl
+ 1;
179 if (!(p
= ndata
= Malloc( nlen
+ 1 )))
181 apparr( p
, data
, cb
- data
); /* zero length if data is null */
187 apparr( p
, section
, sl
- 3 );
191 apparr( p
, key
, kl
- 1 );
194 apparr( p
, value
, vl
);
197 apparr( p
, ce
, len
- (ce
- data
) );
205 iniMerge( char *data
, const char *newdata
)
207 const char *p
, *cb
, *ce
;
208 char *section
= 0, *key
, *value
;
212 for (p
= newdata
;;) {
213 for (; *p
== ' ' || *p
== '\t'; p
++);
221 for (p
++; *p
!= '\n'; p
++)
229 for (; *p
!= ']'; p
++)
230 if (!*p
|| *p
== '\n') /* missing ] */
232 if (!reStrN( §ion
, cb
, p
- cb
))
237 for (; *p
!= '='; p
++)
238 if (!*p
|| *p
== '\n') /* missing = */
240 for (ce
= p
; ce
!= cb
&& (*(ce
- 1) == ' ' || *(ce
- 1) == '\t'); ce
--);
241 if (!strNDup( &key
, cb
, ce
- cb
))
243 for (p
++; *p
== ' ' || *p
== '\t'; p
++);
245 for (; *p
&& *p
!= '\n'; p
++);
246 for (ce
= p
; ce
!= cb
&& (*(ce
- 1) == ' ' || *(ce
- 1) == '\t'); ce
--);
247 if (!strNDup( &value
, cb
, ce
- cb
))
250 data
= iniEntry( data
, section
, key
, value
);