2 * Initialization-File Functions.
4 * Copyright (c) 1993 Miguel de Icaza
6 * 1/Dec o Corrected return values for Get*ProfileString
8 * o Now, if AppName == NULL in Get*ProfileString it returns a list
9 * of the KeyNames (as documented in the MS-SDK).
11 * o if KeyValue == NULL now clears the value in Get*ProfileString
13 * 20/Apr SL - I'm not sure where these definitions came from, but my SDK
14 * has a NULL KeyValue returning a list of KeyNames, and a NULL
15 * AppName undefined. I changed GetSetProfile to match. This makes
16 * PROGMAN.EXE do the right thing.
18 static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza";
31 /* #define DEBUG_PROFILE */
36 #define overflow (next == &CharBuffer [STRSIZE-1])
38 typedef struct TKeys
{
44 typedef struct TSecHeader
{
47 struct TSecHeader
*link
;
50 typedef struct TProfile
{
54 struct TProfile
*link
;
58 TProfile
*Current
= 0;
61 static TSecHeader
*is_loaded (char *FileName
)
66 if (!strcasecmp (FileName
, p
->FileName
)){
75 static char *GetIniFileName(char *name
, char *dir
)
79 if (strchr(name
, '/'))
82 if (strchr(name
, '\\'))
83 return DOS_GetUnixFileName(name
);
89 return DOS_GetUnixFileName(temp
);
92 static TSecHeader
*load (char *filename
, char **pfullname
)
95 TSecHeader
*SecHeader
= 0;
96 char CharBuffer
[STRSIZE
];
102 char path
[MAX_PATH
+1];
107 /* Try the Windows directory */
109 GetWindowsDirectory(path
, sizeof(path
));
110 file
= GetIniFileName(filename
, path
);
112 dprintf_profile(stddeb
,"Load %s\n", file
);
113 f
= fopen(file
, "r");
116 /* Try the path of the current executable */
118 if (GetCurrentTask())
121 GetModuleFileName( GetCurrentTask(), path
, MAX_PATH
);
122 if ((p
= strrchr( path
, '\\' )))
125 file
= GetIniFileName(filename
, path
);
126 f
= fopen(file
, "r");
131 fprintf(stderr
, "profile.c: load() can't find file %s\n", filename
);
132 /* FIXME: we ought to create it now (in which directory?) */
136 *pfullname
= strdup(file
);
137 dprintf_profile(stddeb
,"Loading %s\n", file
);
142 if (c
== EOF
) goto finished
;
148 TSecHeader
*temp
= SecHeader
;
150 SecHeader
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
151 SecHeader
->link
= temp
;
152 SecHeader
->Keys
= NULL
;
155 if (c
== EOF
) goto bad_file
;
156 } while (isspace(c
));
157 bufptr
= lastnonspc
= CharBuffer
;
168 if (c
== EOF
) goto bad_file
;
169 } while(bufsize
< STRSIZE
-1);
171 if (!strlen(CharBuffer
))
172 fprintf(stderr
, "warning: empty section name in ini file\n");
173 SecHeader
->AppName
= strdup (CharBuffer
);
174 dprintf_profile(stddeb
,"%s: section %s\n", file
, CharBuffer
);
176 } else if (SecHeader
) {
177 TKeys
*temp
= SecHeader
->Keys
;
182 bufptr
= lastnonspc
= CharBuffer
;
193 if (c
== EOF
) goto bad_file
;
194 } while(bufsize
< STRSIZE
-1);
196 if (!strlen(CharBuffer
))
197 fprintf(stderr
, "warning: empty key name in ini file\n");
198 SecHeader
->Keys
= (TKeys
*) xmalloc (sizeof (TKeys
));
199 SecHeader
->Keys
->link
= temp
;
200 SecHeader
->Keys
->KeyName
= strdup (CharBuffer
);
202 dprintf_profile(stddeb
,"%s: key %s\n", file
, CharBuffer
);
204 bufptr
= lastnonspc
= CharBuffer
;
211 if (!isspace(c
) || !skipspc
) {
220 } while(bufsize
< STRSIZE
-1);
222 SecHeader
->Keys
->Value
= strdup (CharBuffer
);
223 dprintf_profile (stddeb
, "[%s] (%s)=%s\n", SecHeader
->AppName
,
224 SecHeader
->Keys
->KeyName
, SecHeader
->Keys
->Value
);
230 fprintf(stderr
, "warning: bad ini file\n");
235 static void new_key (TSecHeader
*section
, char *KeyName
, char *Value
)
239 key
= (TKeys
*) xmalloc (sizeof (TKeys
));
240 key
->KeyName
= strdup (KeyName
);
241 key
->Value
= strdup (Value
);
242 key
->link
= section
->Keys
;
246 static short GetSetProfile (int set
, LPSTR AppName
, LPSTR KeyName
,
247 LPSTR Default
, LPSTR ReturnedString
, short Size
,
255 /* Supposedly Default should NEVER be NULL. But sometimes it is. */
259 if (!(section
= is_loaded (FileName
))){
260 New
= (TProfile
*) xmalloc (sizeof (TProfile
));
262 New
->FileName
= strdup (FileName
);
263 New
->Section
= load (FileName
, &New
->FullName
);
264 New
->changed
= FALSE
;
266 section
= New
->Section
;
270 for (; section
; section
= section
->link
){
271 if (strcasecmp (section
->AppName
, AppName
))
274 /* If no key value given, then list all the keys */
275 if ((!KeyName
) && (!set
)){
276 char *p
= ReturnedString
;
280 dprintf_profile(stddeb
,"GetSetProfile // KeyName == NULL, Enumeration !\n");
281 for (key
= section
->Keys
; key
; key
= key
->link
){
283 dprintf_profile(stddeb
,"GetSetProfile // No more storage for enum !\n");
286 slen
= MIN(strlen(key
->KeyName
) + 1, left
);
287 dprintf_profile(stddeb
,"GetSetProfile // strncpy(%p, %p, %d);\n",
288 ReturnedString
, key
->Value
, slen
);
289 strncpy (p
, key
->KeyName
, slen
);
290 dprintf_profile(stddeb
,"GetSetProfile // enum '%s' !\n", p
);
295 dprintf_profile(stddeb
,"GetSetProfile // normal end of enum !\n");
296 return (Size
- 2 - left
);
298 for (key
= section
->Keys
; key
; key
= key
->link
){
300 if (strcasecmp (key
->KeyName
, KeyName
))
304 key
->Value
= strdup (Default
? Default
: "");
305 Current
->changed
=TRUE
;
308 slen
= MIN(strlen(key
->Value
), Size
- 1);
309 ReturnedString
[slen
] = 0;
310 strncpy (ReturnedString
, key
->Value
, slen
);
311 dprintf_profile(stddeb
,"GetSetProfile // Return ``%s''\n", ReturnedString
);
314 /* If Getting the information, then don't write the information
315 to the INI file, need to run a couple of tests with windog */
318 new_key (section
, KeyName
, Default
);
320 int slen
= MIN(strlen(Default
), Size
- 1);
321 ReturnedString
[slen
] = 0;
322 strncpy(ReturnedString
, Default
, slen
);
323 dprintf_profile(stddeb
,"GetSetProfile // Key not found\n");
327 /* Non existent section */
329 section
= (TSecHeader
*) xmalloc (sizeof (TSecHeader
));
330 section
->AppName
= strdup (AppName
);
332 new_key (section
, KeyName
, Default
);
333 section
->link
= Current
->Section
;
334 Current
->Section
= section
;
335 Current
->changed
= TRUE
;
337 int slen
= MIN(strlen(Default
), Size
- 1);
338 ReturnedString
[slen
] = 0;
339 strncpy(ReturnedString
, Default
, slen
);
340 dprintf_profile(stddeb
,"GetSetProfile // Section not found\n");
345 short GetPrivateProfileString (LPSTR AppName
, LPSTR KeyName
,
346 LPSTR Default
, LPSTR ReturnedString
,
347 short Size
, LPSTR FileName
)
351 dprintf_profile(stddeb
,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n",
352 AppName
, KeyName
, Default
, ReturnedString
, Size
, FileName
);
353 v
= GetSetProfile (0,AppName
,KeyName
,Default
,ReturnedString
,Size
,FileName
);
355 return strlen (ReturnedString
);
360 int GetProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR Default
,
361 LPSTR ReturnedString
, int Size
)
363 return GetPrivateProfileString (AppName
, KeyName
, Default
,
364 ReturnedString
, Size
, WIN_INI
);
367 WORD
GetPrivateProfileInt (LPSTR AppName
, LPSTR KeyName
, short Default
,
370 static char IntBuf
[10];
373 sprintf (buf
, "%d", Default
);
375 /* Check the exact semantic with the SDK */
376 GetPrivateProfileString (AppName
, KeyName
, buf
, IntBuf
, 10, File
);
377 if (!strcasecmp (IntBuf
, "true"))
379 if (!strcasecmp (IntBuf
, "yes"))
381 return strtoul( IntBuf
, NULL
, 0 );
384 WORD
GetProfileInt (LPSTR AppName
, LPSTR KeyName
, int Default
)
386 return GetPrivateProfileInt (AppName
, KeyName
, Default
, WIN_INI
);
389 BOOL
WritePrivateProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
,
392 if (!AppName
|| !KeyName
|| !String
) /* Flush file to disk */
394 return GetSetProfile (1, AppName
, KeyName
, String
, "", 0, FileName
);
397 BOOL
WriteProfileString (LPSTR AppName
, LPSTR KeyName
, LPSTR String
)
399 return (WritePrivateProfileString (AppName
, KeyName
, String
, WIN_INI
));
402 static void dump_keys (FILE *profile
, TKeys
*p
)
406 dump_keys (profile
, p
->link
);
407 fprintf (profile
, "%s=%s\r\n", p
->KeyName
, p
->Value
);
410 static void dump_sections (FILE *profile
, TSecHeader
*p
)
414 dump_sections (profile
, p
->link
);
415 fprintf (profile
, "\r\n[%s]\r\n", p
->AppName
);
416 dump_keys (profile
, p
->Keys
);
419 static void dump_profile (TProfile
*p
)
425 dump_profile (p
->link
);
428 if (p
->FullName
&& (profile
= fopen (p
->FullName
, "w")) != NULL
){
429 dump_sections (profile
, p
->Section
);
434 void sync_profiles (void)