source: trunk/src/helpers/xprf2.c@ 51

Last change on this file since 51 was 14, checked in by umoeller, 25 years ago

Major updates; timers, LVM, miscellaneous.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1
2/*
3 *@@sourcefile xprf2.c:
4 * copy-profile functions which use the replacement
5 * profile functions in xprf.c.
6 *
7 * This can be used for a bomb-proof "save system profiles"
8 * (see xprfSaveINIs).
9 *
10 * Usage: All OS/2 programs.
11 *
12 * Function prefixes:
13 * -- xprf* replacement profile (INI) functions
14 *
15 * Note: Version numbering in this file relates to XWorkplace version
16 * numbering.
17 *
18 *@@header "helpers\xprf.h"
19 *@@added V0.9.5 (2000-08-10) [umoeller]
20 */
21
22/*
23 * Copyright (C) 2000 Ulrich M”ller.
24 * This file is part of the "XWorkplace helpers" source package.
25 * This is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published
27 * by the Free Software Foundation, in version 2 as it comes in the
28 * "COPYING" file of the XWorkplace main distribution.
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 */
34
35#define OS2EMX_PLAIN_CHAR
36 // this is needed for "os2emx.h"; if this is defined,
37 // emx will define PSZ as _signed_ char, otherwise
38 // as unsigned char
39
40#define INCL_DOSERRORS
41#define INCL_WINSHELLDATA
42#include <os2.h>
43
44#include <stdlib.h>
45#include <stdio.h>
46#include <string.h>
47
48#include "setup.h" // code generation and debugging options
49
50#include "helpers\dosh.h"
51#include "helpers\prfh.h"
52#include "helpers\stringh.h"
53#include "helpers\xprf.h"
54
55#pragma hdrstop
56
57/*
58 *@@category: Helpers\Profile (INI) replacement functions
59 */
60
61/* ******************************************************************
62 *
63 * Copy API Functions
64 *
65 ********************************************************************/
66
67/*
68 *@@ xprfCopyKey:
69 * copies a single key from an Prf* HINI to an xprf* PXINI.
70 * hiniTarget must therefore have been opened using
71 * xprfOpenProfile.
72 *
73 * This returns 0 (NO_ERROR) if copying succeeded. Otherwise either
74 * an OS/2 error code (ERROR_*) or one of the profile error
75 * codes defined in prfh.h is returned.
76 */
77
78APIRET xprfCopyKey(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
79 PSZ pszSourceApp, // in: source application
80 PSZ pszKey, // in: source/target key
81 PXINI hiniTarget, // in: target profile opened with xprfOpenProfile
82 PSZ pszTargetApp) // in: target app
83{
84 ULONG ulSizeOfData = 0;
85 APIRET arc = NO_ERROR;
86
87 if (PrfQueryProfileSize(hiniSource, pszSourceApp, pszKey, &ulSizeOfData))
88 {
89 PSZ pData = 0;
90
91 // copy data
92 if (ulSizeOfData == 0)
93 {
94 // data size == 0: this shouldn't really happen,
95 // but if it does, we'll just create a NULL string.
96 // Users have reported that some INI files seem to
97 // contain those "empty" keys. I don't see how these
98 // can exist, but they seem to...
99 pData = (PSZ)malloc(1);
100 *pData = 0;
101 }
102 else
103 pData = (PSZ)malloc(ulSizeOfData);
104
105 if (pData)
106 {
107 fflush(stdout);
108 if (PrfQueryProfileData(hiniSource,
109 pszSourceApp,
110 pszKey,
111 pData,
112 &ulSizeOfData))
113 {
114 if (!xprfWriteProfileData(hiniTarget,
115 pszTargetApp,
116 pszKey,
117 pData,
118 ulSizeOfData))
119 arc = PRFERR_WRITE;
120 }
121 else
122 arc = PRFERR_READ;
123
124 free(pData);
125 }
126 else
127 arc = ERROR_NOT_ENOUGH_MEMORY;
128 }
129 else
130 arc = PRFERR_DATASIZE;
131
132 return (arc);
133}
134
135/*
136 *@@ xprfCopyApp:
137 * copies a single application from an Prf* HINI to an xprf* PXINI.
138 * hiniTarget must therefore have been opened using
139 * xprfOpenProfile.
140 *
141 * This calls xprfCopyKey for each key in the application.
142 *
143 * This returns 0 (NO_ERROR) if copying succeeded. Otherwise either
144 * an OS/2 error code (ERROR_*) or one of the profile error
145 * codes defined in prfh.h is returned.
146 */
147
148APIRET xprfCopyApp(HINI hiniSource, // in: source profile (can be HINI_USER or HINI_SYSTEM)
149 PSZ pszSourceApp, // in: source application
150 PXINI hiniTarget, // in: target profile opened with xprfOpenProfile
151 PSZ pszTargetApp, // in: name of pszSourceApp in hiniTarget
152 PSZ pszErrorKey) // out: failing key in case of error; ptr can be NULL
153{
154 APIRET arc = NO_ERROR;
155 PSZ pszKeysList;
156
157 if (pszErrorKey)
158 *pszErrorKey = 0;
159
160 pszKeysList = prfhQueryKeysForApp(hiniSource, pszSourceApp);
161 if (pszKeysList)
162 {
163 PSZ pKey2 = pszKeysList;
164
165 while (*pKey2 != 0)
166 {
167 // copy this key
168 arc = xprfCopyKey(hiniSource,
169 pszSourceApp,
170 pKey2,
171 hiniTarget,
172 pszTargetApp);
173 if (arc)
174 {
175 // error: copy failing key to buffer
176 if (pszErrorKey)
177 strcpy(pszErrorKey, pKey2);
178 break;
179 }
180 pKey2 += strlen(pKey2)+1;
181 } // end while (*pKey2 != 0)
182
183 free (pszKeysList);
184 }
185 else
186 arc = PRFERR_KEYSLIST;
187
188 return (arc);
189}
190
191/*
192 *@@ xprfCopyProfile:
193 * this copies an entire profile.
194 *
195 * The source profile must have been opened using the
196 * regular OS/2 PrfOpenProfile. You can also specify
197 * HINI_USER or HINI_SYSTEM.
198 *
199 * pszNew specifies the file name for the new profile.
200 * This must end in *.INI. The new profile is opened
201 * using xprfOpenProfile, so see additional remarks there.
202 *
203 * This returns 0 (NO_ERROR) on success. Otherwise either
204 * an OS/2 error code (ERROR_*) or one of the profile error
205 * codes defined in prfh.h is returned.
206 */
207
208APIRET xprfCopyProfile(HINI hOld, // in: source profile (can be HINI_USER or HINI_SYSTEM)
209 PSZ pszNew, // in: new filename (can be fully qualified)
210 PFN_PRF_PROGRESS pfnProgressCallback,
211 ULONG ulUser, // in: passed to pfnProgressCallback
212 ULONG ulCount, // in: index of INI being copied (0 <= ulCount <= ulMax)
213 ULONG ulMax) // in: maximum index (for progress); 0 means 1 INI, 1 means 2 INIs, ...
214{
215 APIRET arc = NO_ERROR;
216 PXINI pxiniNew = NULL;
217 ULONG ulSizeOfAppsList;
218
219 if (!pszNew)
220 arc = ERROR_INVALID_PARAMETER;
221 else
222 {
223 DosDelete(pszNew);
224
225 // open new profile
226 arc = xprfOpenProfile(pszNew,
227 &pxiniNew);
228
229 // get size of applications list
230 if (arc == NO_ERROR)
231 {
232 if (!PrfQueryProfileSize(hOld, NULL, NULL, &ulSizeOfAppsList))
233 arc = PRFERR_APPSLIST;
234 else
235 if (ulSizeOfAppsList == 0)
236 arc = PRFERR_APPSLIST;
237
238 if (arc == NO_ERROR)
239 {
240 // get applications list
241 PSZ pApps = (PSZ)malloc(ulSizeOfAppsList);
242 PSZ pApp2 = pApps;
243 if (!PrfQueryProfileData(hOld,
244 NULL,
245 NULL,
246 pApps,
247 &ulSizeOfAppsList))
248 arc = PRFERR_APPSLIST;
249
250 // applications loop
251
252 while ( (*pApp2 != 0)
253 && (arc == NO_ERROR)
254 )
255 {
256 CHAR szErrorKey[1000];
257 // copy application (this will call prfhCopyKey in turn)
258 arc = xprfCopyApp(hOld,
259 pApp2,
260 pxiniNew,
261 pApp2,
262 szErrorKey);
263
264 if (pfnProgressCallback)
265 {
266 ULONG ulNow2, ulMax2;
267 ulNow2 = ((1000*(pApp2-pApps)) / ulSizeOfAppsList) + (ulCount*1000);
268 ulMax2 = (ulMax+1)*1000;
269 if (!pfnProgressCallback(ulUser, ulNow2, ulMax2))
270 // aborted:
271 arc = PRFERR_ABORTED;
272 }
273
274 // go for next app
275 pApp2 += strlen(pApp2)+1;
276
277 } // end while (*pApp2 != 0) && MBID_NOERROR
278
279 if (pApps)
280 free(pApps);
281 }
282
283 xprfCloseProfile(pxiniNew);
284
285 // progress
286 if (pfnProgressCallback)
287 pfnProgressCallback(ulUser, (ulCount+1) * 1000, (ulMax+1) * 1000);
288 }
289 }
290
291 return (arc);
292}
293
294/*
295 *@@ xprfSaveINIs:
296 * this rewrites the OS/2 user and system profiles
297 * (OS2.INI and OS2SYS.INI) to disk. This is done
298 * by doing the following:
299 *
300 * -- First, both profiles are dumped into two temporary
301 * profiles (using xprfCopyProfile on each of them).
302 * These are put into the same directory as the source
303 * profiles (?:\OS2 normally) with a file name extension
304 * of OS2*.XFL.
305 *
306 * -- Only if that succeeded, the original profiles are
307 * renamed to OS2*.BAK. Existing OS2*.BAK files are
308 * deleted.
309 *
310 * -- If that succeded, the temporary OS2*.XFL files are
311 * renamed to OS2*.INI.
312 *
313 * This is now used during XShutdown to dump the system
314 * profiles before shutting down the system. As opposed to
315 * prfhSaveINIs, which was previously used, this does not
316 * use the Prf* functions for the target profiles so that
317 * those ugly "Error saving INI files" errors are less likely.
318 *
319 * This returns 0 (NO_ERROR) if copying succeeded. Otherwise either
320 * an OS/2 error code (ERROR_*) or one of the profile error
321 * codes defined in prfh.h is returned.
322 */
323
324APIRET xprfSaveINIs(HAB hab, // in: anchor block
325 PFN_PRF_PROGRESS pfnProgressCallback,
326 ULONG ulUser)
327{
328 PRFPROFILE Profiles;
329 APIRET arc = NO_ERROR;
330
331 // FILESTATUS3 fs3;
332 CHAR szSysNew[CCHMAXPATH],
333 szUserNew[CCHMAXPATH],
334 szSysBackup[CCHMAXPATH],
335 szUserBackup[CCHMAXPATH];
336
337 /*
338 * get system profiles:
339 *
340 */
341
342 Profiles.cchUserName = Profiles.cchSysName = 0;
343 if (!PrfQueryProfile(hab, &Profiles))
344 arc = PRFERR_QUERY;
345 else
346 {
347 Profiles.pszUserName = (PSZ)malloc(Profiles.cchUserName);
348 Profiles.pszSysName = (PSZ)malloc(Profiles.cchSysName);
349 if ( (Profiles.pszSysName == NULL)
350 || (Profiles.pszUserName == NULL)
351 )
352 arc = PRFERR_QUERY;
353 else
354 if (!PrfQueryProfile(hab, &Profiles))
355 arc = PRFERR_QUERY;
356 }
357
358 if (arc == NO_ERROR)
359 {
360 PSZ _p;
361
362 /*
363 * create new profile names:
364 * same as old profiles, but with *.XFL ext.
365 */
366
367 // system INI
368 strcpy(szSysBackup, Profiles.pszSysName);
369 strcpy(szSysNew, Profiles.pszSysName);
370 _p = strhistr(szSysBackup, ".INI");
371 if (!_p)
372 arc = PRFERR_INVALID_FILE_NAME;
373 else
374 strcpy(_p, ".BAK");
375 _p = strhistr(szSysNew, ".INI");
376 if (!_p)
377 arc = PRFERR_INVALID_FILE_NAME;
378 else
379 strcpy(_p, ".XFL");
380
381 // user INI
382 strcpy(szUserBackup, Profiles.pszUserName);
383 strcpy(szUserNew, Profiles.pszUserName);
384 _p = strhistr(szUserBackup, ".INI");
385 if (!_p)
386 arc = PRFERR_INVALID_FILE_NAME;
387 else
388 strcpy(_p, ".BAK");
389 _p = strhistr(szUserNew, ".INI");
390 if (!_p)
391 arc = PRFERR_INVALID_FILE_NAME;
392 else
393 strcpy(_p, ".XFL");
394
395 /*
396 * create OS2SYS.XFL:
397 *
398 */
399
400 if (arc == NO_ERROR)
401 arc = xprfCopyProfile(HINI_SYSTEM,
402 szSysNew, // new filename
403 pfnProgressCallback,
404 ulUser, 0, 1);
405 /*
406 * create OS2SYS.XFL:
407 *
408 */
409
410 if (arc == NO_ERROR)
411 arc = xprfCopyProfile(HINI_USER,
412 szUserNew, // new filename
413 pfnProgressCallback,
414 ulUser, 1, 1);
415 }
416
417 /*
418 * renaming stuff for OS2SYS.INI
419 *
420 */
421
422 if (arc == NO_ERROR)
423 {
424 // attrib -r -s -h -a OS2SYS.BAK
425 doshSetPathAttr(szSysBackup, FILE_NORMAL);
426 // delete OS2SYS.BAK
427 DosDelete(szSysBackup);
428 // attrib -r -s -h -a OS2SYS.INI
429 doshSetPathAttr(Profiles.pszSysName, FILE_NORMAL);
430 // REN OS2SYS.INI OS2SYS.BAK
431 DosMove(Profiles.pszSysName, szSysBackup);
432 }
433
434 /*
435 * renaming stuff for OS2.INI
436 *
437 */
438
439 if (arc == NO_ERROR)
440 {
441 // attrib -r -s -h -a OS2SYS.BAK
442 doshSetPathAttr(szUserBackup, FILE_NORMAL);
443 // delete OS2SYS.BAK
444 DosDelete(szUserBackup);
445 // attrib -r -s -h -a OS2SYS.INI
446 doshSetPathAttr(Profiles.pszUserName, FILE_NORMAL);
447 // REN OS2SYS.INI OS2SYS.BAK
448 DosMove(Profiles.pszUserName, szUserBackup);
449 }
450
451 if (arc == NO_ERROR)
452 {
453 // finally, replace system profiles
454 arc = DosMove(szSysNew, Profiles.pszSysName);
455 if (arc == NO_ERROR)
456 arc = DosMove(szUserNew, Profiles.pszUserName);
457 }
458
459 if (Profiles.pszSysName)
460 free(Profiles.pszSysName);
461 if (Profiles.pszUserName)
462 free(Profiles.pszUserName);
463
464 return (arc);
465}
466
467// testing
468
469/* BOOL _Optlink fnCallback(ULONG ulUser, ULONG ulNow, ULONG ulMax)
470{
471 printf("\r done %03d%%", ulNow * 100 / ulMax);
472 return (TRUE);
473}
474
475int main(int argc, char* argv[])
476{
477 if (argc != 3)
478 printf("Syntax: xprf2 <source.ini> <target.ini>\n");
479 else
480 {
481 HAB hab = WinInitialize(0);
482
483 // HINI hiniSource = PrfOpenProfile(hab, argv[1]);
484 // if (hiniSource)
485 {
486 APIRET arc = xprfCopyProfile(hiniSource,
487 argv[2],
488 fnCallback,
489 0, 0, 0);
490 xprfSaveProfiles(hab, NULL, 0);
491// if (arc)
492
493
494 // printf("xprfCopyProfile returned %d.\n", arc);
495 }
496 // else
497 // printf("Cannot open %s\n", argv[1]);
498
499 WinTerminate(hab);
500 }
501
502 return (0);
503} */
504
Note: See TracBrowser for help on using the repository browser.