Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / cmd / modutil / install-ds.c
blob2961dc30223bdaed39df94c031a13bc656ef962d
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "install-ds.h"
38 #include <prmem.h>
39 #include <plstr.h>
40 #include <prprf.h>
41 #include <string.h>
43 #define PORT_Strcasecmp PL_strcasecmp
45 #define MODULE_FILE_STRING "ModuleFile"
46 #define MODULE_NAME_STRING "ModuleName"
47 #define MECH_FLAGS_STRING "DefaultMechanismFlags"
48 #define CIPHER_FLAGS_STRING "DefaultCipherFlags"
49 #define FILES_STRING "Files"
50 #define FORWARD_COMPATIBLE_STRING "ForwardCompatible"
51 #define PLATFORMS_STRING "Platforms"
52 #define RELATIVE_DIR_STRING "RelativePath"
53 #define ABSOLUTE_DIR_STRING "AbsolutePath"
54 #define FILE_PERMISSIONS_STRING "FilePermissions"
55 #define EQUIVALENT_PLATFORM_STRING "EquivalentPlatform"
56 #define EXECUTABLE_STRING "Executable"
58 #define DEFAULT_PERMISSIONS 0777
60 #define PLATFORM_SEPARATOR_CHAR ':'
62 /* Error codes */
63 enum {
64 BOGUS_RELATIVE_DIR=0,
65 BOGUS_ABSOLUTE_DIR,
66 BOGUS_FILE_PERMISSIONS,
67 NO_RELATIVE_DIR,
68 NO_ABSOLUTE_DIR,
69 EMPTY_PLATFORM_STRING,
70 BOGUS_PLATFORM_STRING,
71 REPEAT_MODULE_FILE,
72 REPEAT_MODULE_NAME,
73 BOGUS_MODULE_FILE,
74 BOGUS_MODULE_NAME,
75 REPEAT_MECH,
76 BOGUS_MECH_FLAGS,
77 REPEAT_CIPHER,
78 BOGUS_CIPHER_FLAGS,
79 REPEAT_FILES,
80 REPEAT_EQUIV,
81 BOGUS_EQUIV,
82 EQUIV_TOO_MUCH_INFO,
83 NO_FILES,
84 NO_MODULE_FILE,
85 NO_MODULE_NAME,
86 NO_PLATFORMS,
87 EQUIV_LOOP,
88 UNKNOWN_MODULE_FILE
91 /* Indexed by the above error codes */
92 static const char *errString[] = {
93 "%s: Invalid relative directory",
94 "%s: Invalid absolute directory",
95 "%s: Invalid file permissions",
96 "%s: No relative directory specified",
97 "%s: No absolute directory specified",
98 "Empty string given for platform name",
99 "%s: invalid platform string",
100 "More than one ModuleFile entry given for platform %s",
101 "More than one ModuleName entry given for platform %s",
102 "Invalid ModuleFile specification for platform %s",
103 "Invalid ModuleName specification for platform %s",
104 "More than one DefaultMechanismFlags entry given for platform %s",
105 "Invalid DefaultMechanismFlags specification for platform %s",
106 "More than one DefaultCipherFlags entry given for platform %s",
107 "Invalid DefaultCipherFlags entry given for platform %s",
108 "More than one Files entry given for platform %s",
109 "More than one EquivalentPlatform entry given for platform %s",
110 "Invalid EquivalentPlatform specification for platform %s",
111 "Module %s uses an EquivalentPlatform but also specifies its own"
112 " information",
113 "No Files specification in module %s",
114 "No ModuleFile specification in module %s",
115 "No ModuleName specification in module %s",
116 "No Platforms specification in installer script",
117 "Platform %s has an equivalency loop",
118 "Module file \"%s\" in platform \"%s\" does not exist"
121 static char* PR_Strdup(const char* str);
123 #define PAD(x) {int i; for(i=0;i<x;i++) printf(" ");}
124 #define PADINC 4
126 Pk11Install_File*
127 Pk11Install_File_new()
129 Pk11Install_File* new_this;
130 new_this = (Pk11Install_File*)PR_Malloc(sizeof(Pk11Install_File));
131 Pk11Install_File_init(new_this);
132 return new_this;
135 void
136 Pk11Install_File_init(Pk11Install_File* _this)
138 _this->jarPath=NULL;
139 _this->relativePath=NULL;
140 _this->absolutePath=NULL;
141 _this->executable=PR_FALSE;
142 _this->permissions=0;
146 //////////////////////////////////////////////////////////////////////////
147 // Method: ~Pk11Install_File
148 // Class: Pk11Install_File
149 // Notes: Destructor.
151 void
152 Pk11Install_File_delete(Pk11Install_File* _this)
154 Pk11Install_File_Cleanup(_this);
158 //////////////////////////////////////////////////////////////////////////
159 // Method: Cleanup
160 // Class: Pk11Install_File
162 void
163 Pk11Install_File_Cleanup(Pk11Install_File* _this)
165 if(_this->jarPath) {
166 PR_Free(_this->jarPath);
167 _this->jarPath = NULL;
169 if(_this->relativePath) {
170 PR_Free(_this->relativePath);
171 _this->relativePath = NULL;
173 if(_this->absolutePath) {
174 PR_Free(_this->absolutePath);
175 _this->absolutePath = NULL;
178 _this->permissions = 0;
179 _this->executable = PR_FALSE;
183 //////////////////////////////////////////////////////////////////////////
184 // Method: Generate
185 // Class: Pk11Install_File
186 // Notes: Creates a file data structure from a syntax tree.
187 // Returns: NULL for success, otherwise an error message.
189 char*
190 Pk11Install_File_Generate(Pk11Install_File* _this,
191 const Pk11Install_Pair *pair)
193 Pk11Install_ListIter *iter;
194 Pk11Install_Value *val;
195 Pk11Install_Pair *subpair;
196 Pk11Install_ListIter *subiter;
197 Pk11Install_Value *subval;
198 char* errStr;
199 char *endp;
200 PRBool gotPerms;
202 iter=NULL;
203 subiter=NULL;
204 errStr=NULL;
205 gotPerms=PR_FALSE;
207 /* Clear out old values */
208 Pk11Install_File_Cleanup(_this);
210 _this->jarPath = PR_Strdup(pair->key);
212 /* Go through all the pairs under this file heading */
213 iter = Pk11Install_ListIter_new(pair->list);
214 for( ; (val = iter->current); Pk11Install_ListIter_nextItem(iter)) {
215 if(val->type == PAIR_VALUE) {
216 subpair = val->pair;
218 /* Relative directory */
219 if(!PORT_Strcasecmp(subpair->key, RELATIVE_DIR_STRING)) {
220 subiter = Pk11Install_ListIter_new(subpair->list);
221 subval = subiter->current;
222 if(!subval || (subval->type != STRING_VALUE)){
223 errStr = PR_smprintf(errString[BOGUS_RELATIVE_DIR],
224 _this->jarPath);
225 goto loser;
227 _this->relativePath = PR_Strdup(subval->string);
228 Pk11Install_ListIter_delete(subiter);
229 subiter = NULL;
231 /* Absolute directory */
232 } else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
233 subiter = Pk11Install_ListIter_new(subpair->list);
234 subval = subiter->current;
235 if(!subval || (subval->type != STRING_VALUE)){
236 errStr = PR_smprintf(errString[BOGUS_ABSOLUTE_DIR],
237 _this->jarPath);
238 goto loser;
240 _this->absolutePath = PR_Strdup(subval->string);
241 Pk11Install_ListIter_delete(subiter);
242 subiter = NULL;
244 /* file permissions */
245 } else if( !PORT_Strcasecmp(subpair->key,
246 FILE_PERMISSIONS_STRING)) {
247 subiter = Pk11Install_ListIter_new(subpair->list);
248 subval = subiter->current;
249 if(!subval || (subval->type != STRING_VALUE)){
250 errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
251 _this->jarPath);
252 goto loser;
254 _this->permissions = (int) strtol(subval->string, &endp, 8);
255 if(*endp != '\0' || subval->string == "\0") {
256 errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
257 _this->jarPath);
258 goto loser;
260 gotPerms = PR_TRUE;
261 Pk11Install_ListIter_delete(subiter);
262 subiter = NULL;
264 } else {
265 if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
266 _this->executable = PR_TRUE;
271 /* Default permission value */
272 if(!gotPerms) {
273 _this->permissions = DEFAULT_PERMISSIONS;
276 /* Make sure we got all the information */
277 if(!_this->relativePath && !_this->absolutePath) {
278 errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath);
279 goto loser;
281 #if 0
282 if(!_this->relativePath ) {
283 errStr = PR_smprintf(errString[NO_RELATIVE_DIR], _this->jarPath);
284 goto loser;
286 if(!_this->absolutePath) {
287 errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath);
288 goto loser;
290 #endif
292 loser:
293 if(iter) {
294 Pk11Install_ListIter_delete(iter);
295 PR_Free(iter);
297 if(subiter) {
298 Pk11Install_ListIter_delete(subiter);
299 PR_Free(subiter);
301 return errStr;
305 //////////////////////////////////////////////////////////////////////////
306 // Method: Print
307 // Class: Pk11Install_File
309 void
310 Pk11Install_File_Print(Pk11Install_File* _this, int pad)
312 PAD(pad); printf("jarPath: %s\n",
313 _this->jarPath ? _this->jarPath : "<NULL>");
314 PAD(pad); printf("relativePath: %s\n",
315 _this->relativePath ? _this->relativePath: "<NULL>");
316 PAD(pad); printf("absolutePath: %s\n",
317 _this->absolutePath ? _this->absolutePath: "<NULL>");
318 PAD(pad); printf("permissions: %o\n", _this->permissions);
321 Pk11Install_PlatformName*
322 Pk11Install_PlatformName_new()
324 Pk11Install_PlatformName* new_this;
325 new_this = (Pk11Install_PlatformName*)
326 PR_Malloc(sizeof(Pk11Install_PlatformName));
327 Pk11Install_PlatformName_init(new_this);
328 return new_this;
331 void
332 Pk11Install_PlatformName_init(Pk11Install_PlatformName* _this)
334 _this->OS = NULL;
335 _this->verString = NULL;
336 _this->numDigits = 0;
337 _this->arch = NULL;
341 //////////////////////////////////////////////////////////////////////////
342 // Method: ~Pk11Install_PlatformName
343 // Class: Pk11Install_PlatformName
345 void
346 Pk11Install_PlatformName_delete(Pk11Install_PlatformName* _this)
348 Pk11Install_PlatformName_Cleanup(_this);
352 //////////////////////////////////////////////////////////////////////////
353 // Method: Cleanup
354 // Class: Pk11Install_PlatformName
356 void
357 Pk11Install_PlatformName_Cleanup(Pk11Install_PlatformName* _this)
359 if(_this->OS) {
360 PR_Free(_this->OS);
361 _this->OS = NULL;
363 if(_this->verString) {
364 int i;
365 for (i=0; i<_this->numDigits; i++) {
366 PR_Free(_this->verString[i]);
368 PR_Free(_this->verString);
369 _this->verString = NULL;
371 if(_this->arch) {
372 PR_Free(_this->arch);
373 _this->arch = NULL;
375 _this->numDigits = 0;
379 //////////////////////////////////////////////////////////////////////////
380 // Method: Generate
381 // Class: Pk11Install_PlatformName
382 // Notes: Extracts the information from a platform string.
384 char*
385 Pk11Install_PlatformName_Generate(Pk11Install_PlatformName* _this,
386 const char *str)
388 char *errStr;
389 char *copy;
390 char *end, *start; /* start and end of a section (OS, version, arch)*/
391 char *pend, *pstart; /* start and end of one portion of version*/
392 char *endp; /* used by strtol*/
393 int periods, i;
395 errStr=NULL;
396 copy=NULL;
398 if(!str) {
399 errStr = PR_smprintf(errString[EMPTY_PLATFORM_STRING]);
400 goto loser;
402 copy = PR_Strdup(str);
405 // Get the OS
407 end = strchr(copy, PLATFORM_SEPARATOR_CHAR);
408 if(!end || end==copy) {
409 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
410 goto loser;
412 *end = '\0';
414 _this->OS = PR_Strdup(copy);
417 // Get the digits of the version of form: x.x.x (arbitrary number of digits)
420 start = end+1;
421 end = strchr(start, PLATFORM_SEPARATOR_CHAR);
422 if(!end) {
423 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
424 goto loser;
426 *end = '\0';
428 if(end!=start) {
429 /* Find out how many periods*/
430 periods = 0;
431 pstart = start;
432 while( (pend=strchr(pstart, '.')) ) {
433 periods++;
434 pstart = pend+1;
436 _this->numDigits= 1+ periods;
437 _this->verString = (char**)PR_Malloc(sizeof(char*)*_this->numDigits);
439 pstart = start;
440 i = 0;
441 /* Get the digits before each period*/
442 while( (pend=strchr(pstart, '.')) ) {
443 if(pend == pstart) {
444 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
445 goto loser;
447 *pend = '\0';
448 _this->verString[i] = PR_Strdup(pstart);
449 endp = pend;
450 if(endp==pstart || (*endp != '\0')) {
451 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
452 goto loser;
454 pstart = pend+1;
455 i++;
457 /* Last digit comes after the last period*/
458 if(*pstart == '\0') {
459 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
460 goto loser;
462 _this->verString[i] = PR_Strdup(pstart);
464 if(endp==pstart || (*endp != '\0')) {
465 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
466 goto loser;
469 } else {
470 _this->verString = NULL;
471 _this->numDigits = 0;
475 // Get the architecture
477 start = end+1;
478 if( strchr(start, PLATFORM_SEPARATOR_CHAR) ) {
479 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
480 goto loser;
482 _this->arch = PR_Strdup(start);
484 if(copy) {
485 PR_Free(copy);
487 return NULL;
488 loser:
489 if(_this->OS) {
490 PR_Free(_this->OS);
491 _this->OS = NULL;
493 if(_this->verString) {
494 for (i=0; i<_this->numDigits; i++) {
495 PR_Free(_this->verString[i]);
497 PR_Free(_this->verString);
498 _this->verString = NULL;
500 _this->numDigits = 0;
501 if(_this->arch) {
502 PR_Free(_this->arch);
503 _this->arch = NULL;
506 return errStr;
510 //////////////////////////////////////////////////////////////////////////
511 // Method: operator ==
512 // Class: Pk11Install_PlatformName
513 // Returns: PR_TRUE if the platform have the same OS, arch, and version
515 PRBool
516 Pk11Install_PlatformName_equal(Pk11Install_PlatformName* _this,
517 Pk11Install_PlatformName* cmp)
519 int i;
521 if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) {
522 return PR_FALSE;
525 if( PORT_Strcasecmp(_this->OS, cmp->OS) ||
526 PORT_Strcasecmp(_this->arch, cmp->arch) ||
527 _this->numDigits != cmp->numDigits ) {
528 return PR_FALSE;
531 for(i=0; i < _this->numDigits; i++) {
532 if(PORT_Strcasecmp(_this->verString[i], cmp->verString[i])) {
533 return PR_FALSE;
536 return PR_TRUE;
540 //////////////////////////////////////////////////////////////////////////
541 // Method: operator <=
542 // Class: Pk11Install_PlatformName
543 // Returns: PR_TRUE if the platform have the same OS and arch and a lower
544 // or equal release.
546 PRBool
547 Pk11Install_PlatformName_lteq(Pk11Install_PlatformName* _this,
548 Pk11Install_PlatformName* cmp)
550 return (Pk11Install_PlatformName_equal(_this,cmp) ||
551 Pk11Install_PlatformName_lt(_this,cmp)) ? PR_TRUE : PR_FALSE;
555 //////////////////////////////////////////////////////////////////////////
556 // Method: operator <
557 // Class: Pk11Install_PlatformName
558 // Returns: PR_TRUE if the platform have the same OS and arch and a greater
559 // release.
561 PRBool
562 Pk11Install_PlatformName_lt(Pk11Install_PlatformName* _this,
563 Pk11Install_PlatformName* cmp)
565 int i, scmp;
567 if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) {
568 return PR_FALSE;
571 if( PORT_Strcasecmp(_this->OS, cmp->OS) ) {
572 return PR_FALSE;
574 if( PORT_Strcasecmp(_this->arch, cmp->arch) ) {
575 return PR_FALSE;
578 for(i=0; (i < _this->numDigits) && (i < cmp->numDigits); i++) {
579 scmp = PORT_Strcasecmp(_this->verString[i], cmp->verString[i]);
580 if (scmp > 0) {
581 return PR_FALSE;
582 } else if (scmp < 0) {
583 return PR_TRUE;
586 /* All the digits they have in common are the same. */
587 if(_this->numDigits < cmp->numDigits) {
588 return PR_TRUE;
591 return PR_FALSE;
595 //////////////////////////////////////////////////////////////////////////
596 // Method: GetString
597 // Class: Pk11Install_PlatformName
598 // Returns: String composed of OS, release, and architecture separated
599 // by the separator char. Memory is allocated by this function
600 // but is the responsibility of the caller to de-allocate.
602 char*
603 Pk11Install_PlatformName_GetString(Pk11Install_PlatformName* _this)
605 char *ret;
606 char *ver;
607 char *OS_;
608 char *arch_;
610 OS_=NULL;
611 arch_=NULL;
613 OS_ = _this->OS ? _this->OS : "";
614 arch_ = _this->arch ? _this->arch : "";
616 ver = Pk11Install_PlatformName_GetVerString(_this);
617 ret = PR_smprintf("%s%c%s%c%s", OS_, PLATFORM_SEPARATOR_CHAR, ver,
618 PLATFORM_SEPARATOR_CHAR, arch_);
620 PR_Free(ver);
622 return ret;
626 //////////////////////////////////////////////////////////////////////////
627 // Method: GetVerString
628 // Class: Pk11Install_PlatformName
629 // Returns: The version string for this platform, in the form x.x.x with an
630 // arbitrary number of digits. Memory allocated by function,
631 // must be de-allocated by caller.
633 char*
634 Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this)
636 char *tmp;
637 char *ret;
638 int i;
639 char buf[80];
641 tmp = (char*)PR_Malloc(80*_this->numDigits+1);
642 tmp[0] = '\0';
644 for(i=0; i < _this->numDigits-1; i++) {
645 sprintf(buf, "%s.", _this->verString[i]);
646 strcat(tmp, buf);
648 if(i < _this->numDigits) {
649 sprintf(buf, "%s", _this->verString[i]);
650 strcat(tmp, buf);
653 ret = PR_Strdup(tmp);
654 free(tmp);
656 return ret;
660 //////////////////////////////////////////////////////////////////////////
661 // Method: Print
662 // Class: Pk11Install_PlatformName
664 void
665 Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad)
667 PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>");
668 PAD(pad); printf("Digits: ");
669 if(_this->numDigits == 0) {
670 printf("None\n");
671 } else {
672 printf("%s\n", Pk11Install_PlatformName_GetVerString(_this));
674 PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>");
677 Pk11Install_Platform*
678 Pk11Install_Platform_new()
680 Pk11Install_Platform* new_this;
681 new_this = (Pk11Install_Platform*)PR_Malloc(sizeof(Pk11Install_Platform));
682 Pk11Install_Platform_init(new_this);
683 return new_this;
686 void
687 Pk11Install_Platform_init(Pk11Install_Platform* _this)
689 Pk11Install_PlatformName_init(&_this->name);
690 Pk11Install_PlatformName_init(&_this->equivName);
691 _this->equiv = NULL;
692 _this->usesEquiv = PR_FALSE;
693 _this->moduleFile = NULL;
694 _this->moduleName = NULL;
695 _this->modFile = -1;
696 _this->mechFlags = 0;
697 _this->cipherFlags = 0;
698 _this->files = NULL;
699 _this->numFiles = 0;
703 //////////////////////////////////////////////////////////////////////////
704 // Method: ~Pk11Install_Platform
705 // Class: Pk11Install_Platform
707 void
708 Pk11Install_Platform_delete(Pk11Install_Platform* _this)
710 Pk11Install_Platform_Cleanup(_this);
714 //////////////////////////////////////////////////////////////////////////
715 // Method: Cleanup
716 // Class: Pk11Install_Platform
718 void
719 Pk11Install_Platform_Cleanup(Pk11Install_Platform* _this)
721 int i;
722 if(_this->moduleFile) {
723 PR_Free(_this->moduleFile);
724 _this->moduleFile = NULL;
726 if(_this->moduleName) {
727 PR_Free(_this->moduleName);
728 _this->moduleName = NULL;
730 if(_this->files) {
731 for (i=0;i<_this->numFiles;i++) {
732 Pk11Install_File_delete(&_this->files[i]);
734 PR_Free(_this->files);
735 _this->files = NULL;
737 _this->equiv = NULL;
738 _this->usesEquiv = PR_FALSE;
739 _this->modFile = -1;
740 _this->numFiles = 0;
741 _this->mechFlags = _this->cipherFlags = 0;
745 //////////////////////////////////////////////////////////////////////////
746 // Method: Generate
747 // Class: Pk11Install_Platform
748 // Notes: Creates a platform data structure from a syntax tree.
749 // Returns: NULL for success, otherwise an error message.
751 char*
752 Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
753 const Pk11Install_Pair *pair)
755 char* errStr;
756 char* endptr;
757 char* tmp;
758 int i;
759 Pk11Install_ListIter *iter;
760 Pk11Install_Value *val;
761 Pk11Install_Value *subval;
762 Pk11Install_Pair *subpair;
763 Pk11Install_ListIter *subiter;
764 PRBool gotModuleFile, gotModuleName, gotMech,
765 gotCipher, gotFiles, gotEquiv;
767 errStr=NULL;
768 iter=subiter=NULL;
769 val=subval=NULL;
770 subpair=NULL;
771 gotModuleFile=gotModuleName=gotMech=gotCipher=gotFiles=gotEquiv=PR_FALSE;
772 Pk11Install_Platform_Cleanup(_this);
774 errStr = Pk11Install_PlatformName_Generate(&_this->name,pair->key);
775 if(errStr) {
776 tmp = PR_smprintf("%s: %s", pair->key, errStr);
777 PR_smprintf_free(errStr);
778 errStr = tmp;
779 goto loser;
782 iter = Pk11Install_ListIter_new(pair->list);
783 for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) {
784 if(val->type==PAIR_VALUE) {
785 subpair = val->pair;
787 if( !PORT_Strcasecmp(subpair->key, MODULE_FILE_STRING)) {
788 if(gotModuleFile) {
789 errStr = PR_smprintf(errString[REPEAT_MODULE_FILE],
790 Pk11Install_PlatformName_GetString(&_this->name));
791 goto loser;
793 subiter = Pk11Install_ListIter_new(subpair->list);
794 subval = subiter->current;
795 if(!subval || (subval->type != STRING_VALUE)) {
796 errStr = PR_smprintf(errString[BOGUS_MODULE_FILE],
797 Pk11Install_PlatformName_GetString(&_this->name));
798 goto loser;
800 _this->moduleFile = PR_Strdup(subval->string);
801 Pk11Install_ListIter_delete(subiter);
802 PR_Free(subiter);
803 subiter = NULL;
804 gotModuleFile = PR_TRUE;
805 } else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
806 if(gotModuleName) {
807 errStr = PR_smprintf(errString[REPEAT_MODULE_NAME],
808 Pk11Install_PlatformName_GetString(&_this->name));
809 goto loser;
811 subiter = Pk11Install_ListIter_new(subpair->list);
812 subval = subiter->current;
813 if(!subval || (subval->type != STRING_VALUE)) {
814 errStr = PR_smprintf(errString[BOGUS_MODULE_NAME],
815 Pk11Install_PlatformName_GetString(&_this->name));
816 goto loser;
818 _this->moduleName = PR_Strdup(subval->string);
819 Pk11Install_ListIter_delete(subiter);
820 PR_Free(subiter);
821 subiter = NULL;
822 gotModuleName = PR_TRUE;
823 } else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
824 endptr=NULL;
826 if(gotMech) {
827 errStr = PR_smprintf(errString[REPEAT_MECH],
828 Pk11Install_PlatformName_GetString(&_this->name));
829 goto loser;
831 subiter = Pk11Install_ListIter_new(subpair->list);
832 subval = subiter->current;
833 if(!subval || (subval->type != STRING_VALUE)) {
834 errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS],
835 Pk11Install_PlatformName_GetString(&_this->name));
836 goto loser;
838 _this->mechFlags = strtol(subval->string, &endptr, 0);
839 if(*endptr!='\0' || (endptr==subval->string) ) {
840 errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS],
841 Pk11Install_PlatformName_GetString(&_this->name));
842 goto loser;
844 Pk11Install_ListIter_delete(subiter);
845 PR_Free(subiter);
846 subiter=NULL;
847 gotMech = PR_TRUE;
848 } else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
849 endptr=NULL;
851 if(gotCipher) {
852 errStr = PR_smprintf(errString[REPEAT_CIPHER],
853 Pk11Install_PlatformName_GetString(&_this->name));
854 goto loser;
856 subiter = Pk11Install_ListIter_new(subpair->list);
857 subval = subiter->current;
858 if(!subval || (subval->type != STRING_VALUE)) {
859 errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS],
860 Pk11Install_PlatformName_GetString(&_this->name));
861 goto loser;
863 _this->cipherFlags = strtol(subval->string, &endptr, 0);
864 if(*endptr!='\0' || (endptr==subval->string) ) {
865 errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS],
866 Pk11Install_PlatformName_GetString(&_this->name));
867 goto loser;
869 Pk11Install_ListIter_delete(subiter);
870 PR_Free(subiter);
871 subiter=NULL;
872 gotCipher = PR_TRUE;
873 } else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
874 if(gotFiles) {
875 errStr = PR_smprintf(errString[REPEAT_FILES],
876 Pk11Install_PlatformName_GetString(&_this->name));
877 goto loser;
879 subiter = Pk11Install_ListIter_new(subpair->list);
880 _this->numFiles = subpair->list->numPairs;
881 _this->files = (Pk11Install_File*)
882 PR_Malloc(sizeof(Pk11Install_File)*_this->numFiles);
883 for(i=0; i < _this->numFiles; i++,
884 Pk11Install_ListIter_nextItem(subiter)) {
885 Pk11Install_File_init(&_this->files[i]);
886 val = subiter->current;
887 if(val && (val->type==PAIR_VALUE)) {
888 errStr = Pk11Install_File_Generate(&_this->files[i],val->pair);
889 if(errStr) {
890 tmp = PR_smprintf("%s: %s",
891 Pk11Install_PlatformName_GetString(&_this->name),errStr);
892 PR_smprintf_free(errStr);
893 errStr = tmp;
894 goto loser;
898 gotFiles = PR_TRUE;
899 } else if(!PORT_Strcasecmp(subpair->key,
900 EQUIVALENT_PLATFORM_STRING)) {
901 if(gotEquiv) {
902 errStr = PR_smprintf(errString[REPEAT_EQUIV],
903 Pk11Install_PlatformName_GetString(&_this->name));
904 goto loser;
906 subiter = Pk11Install_ListIter_new(subpair->list);
907 subval = subiter->current;
908 if(!subval || (subval->type != STRING_VALUE) ) {
909 errStr = PR_smprintf(errString[BOGUS_EQUIV],
910 Pk11Install_PlatformName_GetString(&_this->name));
911 goto loser;
913 errStr = Pk11Install_PlatformName_Generate(&_this->equivName,
914 subval->string);
915 if(errStr) {
916 tmp = PR_smprintf("%s: %s",
917 Pk11Install_PlatformName_GetString(&_this->name), errStr);
918 tmp = PR_smprintf("%s: %s",
919 Pk11Install_PlatformName_GetString(&_this->name), errStr);
920 PR_smprintf_free(errStr);
921 errStr = tmp;
922 goto loser;
924 _this->usesEquiv = PR_TRUE;
929 /* Make sure we either have an EquivalentPlatform or all the other info */
930 if(_this->usesEquiv &&
931 (gotFiles || gotModuleFile || gotModuleName || gotMech || gotCipher)) {
932 errStr = PR_smprintf(errString[EQUIV_TOO_MUCH_INFO],
933 Pk11Install_PlatformName_GetString(&_this->name));
934 goto loser;
936 if(!gotFiles && !_this->usesEquiv) {
937 errStr = PR_smprintf(errString[NO_FILES],
938 Pk11Install_PlatformName_GetString(&_this->name));
939 goto loser;
941 if(!gotModuleFile && !_this->usesEquiv) {
942 errStr= PR_smprintf(errString[NO_MODULE_FILE],
943 Pk11Install_PlatformName_GetString(&_this->name));
944 goto loser;
946 if(!gotModuleName && !_this->usesEquiv) {
947 errStr = PR_smprintf(errString[NO_MODULE_NAME],
948 Pk11Install_PlatformName_GetString(&_this->name));
949 goto loser;
952 /* Point the modFile pointer to the correct file */
953 if(gotModuleFile) {
954 for(i=0; i < _this->numFiles; i++) {
955 if(!PORT_Strcasecmp(_this->moduleFile, _this->files[i].jarPath) ) {
956 _this->modFile = i;
957 break;
960 if(_this->modFile==-1) {
961 errStr = PR_smprintf(errString[UNKNOWN_MODULE_FILE],
962 _this->moduleFile,
963 Pk11Install_PlatformName_GetString(&_this->name));
964 goto loser;
968 loser:
969 if(iter) {
970 PR_Free(iter);
972 if(subiter) {
973 PR_Free(subiter);
975 return errStr;
979 //////////////////////////////////////////////////////////////////////////
980 // Method: Print
981 // Class: Pk11Install_Platform
983 void
984 Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad)
986 int i;
988 PAD(pad); printf("Name:\n");
989 Pk11Install_PlatformName_Print(&_this->name,pad+PADINC);
990 PAD(pad); printf("equivName:\n");
991 Pk11Install_PlatformName_Print(&_this->equivName,pad+PADINC);
992 PAD(pad);
993 if(_this->usesEquiv) {
994 printf("Uses equiv, which points to:\n");
995 Pk11Install_Platform_Print(_this->equiv,pad+PADINC);
996 } else {
997 printf("Doesn't use equiv\n");
999 PAD(pad);
1000 printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile
1001 : "<NULL>");
1002 PAD(pad); printf("mechFlags: %lx\n", _this->mechFlags);
1003 PAD(pad); printf("cipherFlags: %lx\n", _this->cipherFlags);
1004 PAD(pad); printf("Files:\n");
1005 for(i=0; i < _this->numFiles; i++) {
1006 Pk11Install_File_Print(&_this->files[i],pad+PADINC);
1007 PAD(pad); printf("--------------------\n");
1012 //////////////////////////////////////////////////////////////////////////
1013 // Method: Pk11Install_Info
1014 // Class: Pk11Install_Info
1016 Pk11Install_Info*
1017 Pk11Install_Info_new()
1019 Pk11Install_Info* new_this;
1020 new_this = (Pk11Install_Info*)PR_Malloc(sizeof(Pk11Install_Info));
1021 Pk11Install_Info_init(new_this);
1022 return new_this;
1025 void
1026 Pk11Install_Info_init(Pk11Install_Info* _this)
1028 _this->platforms = NULL;
1029 _this->numPlatforms = 0;
1030 _this->forwardCompatible = NULL;
1031 _this->numForwardCompatible = 0;
1035 //////////////////////////////////////////////////////////////////////////
1036 // Method: ~Pk11Install_Info
1037 // Class: Pk11Install_Info
1039 void
1040 Pk11Install_Info_delete(Pk11Install_Info* _this)
1042 Pk11Install_Info_Cleanup(_this);
1046 //////////////////////////////////////////////////////////////////////////
1047 // Method: Cleanup
1048 // Class: Pk11Install_Info
1050 void
1051 Pk11Install_Info_Cleanup(Pk11Install_Info* _this)
1053 int i;
1054 if(_this->platforms) {
1055 for (i=0;i<_this->numPlatforms;i++) {
1056 Pk11Install_Platform_delete(&_this->platforms[i]);
1058 PR_Free(&_this->platforms);
1059 _this->platforms = NULL;
1060 _this->numPlatforms = 0;
1063 if(_this->forwardCompatible) {
1064 for (i=0;i<_this->numForwardCompatible;i++) {
1065 Pk11Install_PlatformName_delete(&_this->forwardCompatible[i]);
1067 PR_Free(&_this->forwardCompatible);
1068 _this->numForwardCompatible = 0;
1073 //////////////////////////////////////////////////////////////////////////
1074 // Method: Generate
1075 // Class: Pk11Install_Info
1076 // Takes: Pk11Install_ValueList *list, the top-level list
1077 // resulting from parsing an installer file.
1078 // Returns: char*, NULL if successful, otherwise an error string.
1079 // Caller is responsible for freeing memory.
1081 char*
1082 Pk11Install_Info_Generate(Pk11Install_Info* _this,
1083 const Pk11Install_ValueList *list)
1085 char *errStr;
1086 Pk11Install_ListIter *iter;
1087 Pk11Install_Value *val;
1088 Pk11Install_Pair *pair;
1089 Pk11Install_ListIter *subiter;
1090 Pk11Install_Value *subval;
1091 Pk11Install_Platform *first, *second;
1092 int i, j;
1094 errStr=NULL;
1095 iter=subiter=NULL;
1096 Pk11Install_Info_Cleanup(_this);
1098 iter = Pk11Install_ListIter_new(list);
1099 for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) {
1100 if(val->type == PAIR_VALUE) {
1101 pair = val->pair;
1103 if(!PORT_Strcasecmp(pair->key, FORWARD_COMPATIBLE_STRING)) {
1104 subiter = Pk11Install_ListIter_new(pair->list);
1105 _this->numForwardCompatible = pair->list->numStrings;
1106 _this->forwardCompatible = (Pk11Install_PlatformName*)
1107 PR_Malloc(sizeof(Pk11Install_PlatformName)*
1108 _this->numForwardCompatible);
1109 for(i=0; i < _this->numForwardCompatible; i++,
1110 Pk11Install_ListIter_nextItem(subiter)) {
1111 subval = subiter->current;
1112 if(subval->type == STRING_VALUE) {
1113 errStr = Pk11Install_PlatformName_Generate(
1114 &_this->forwardCompatible[i], subval->string);
1115 if(errStr) {
1116 goto loser;
1120 Pk11Install_ListIter_delete(subiter);
1121 PR_Free(subiter);
1122 subiter = NULL;
1123 } else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
1124 subiter = Pk11Install_ListIter_new(pair->list);
1125 _this->numPlatforms = pair->list->numPairs;
1126 _this->platforms = (Pk11Install_Platform*)
1127 PR_Malloc(sizeof(Pk11Install_Platform)*
1128 _this->numPlatforms);
1129 for(i=0; i < _this->numPlatforms; i++,
1130 Pk11Install_ListIter_nextItem(subiter)) {
1131 Pk11Install_Platform_init(&_this->platforms[i]);
1132 subval = subiter->current;
1133 if(subval->type == PAIR_VALUE) {
1134 errStr = Pk11Install_Platform_Generate(&_this->platforms[i],subval->pair);
1135 if(errStr) {
1136 goto loser;
1140 Pk11Install_ListIter_delete(subiter);
1141 PR_Free(subiter);
1142 subiter = NULL;
1147 if(_this->numPlatforms == 0) {
1148 errStr = PR_smprintf(errString[NO_PLATFORMS]);
1149 goto loser;
1154 // Now process equivalent platforms
1157 // First the naive pass
1159 for(i=0; i < _this->numPlatforms; i++) {
1160 if(_this->platforms[i].usesEquiv) {
1161 _this->platforms[i].equiv = NULL;
1162 for(j=0; j < _this->numPlatforms; j++) {
1163 if (Pk11Install_PlatformName_equal(&_this->platforms[i].equivName,
1164 &_this->platforms[j].name)) {
1165 if(i==j) {
1166 errStr = PR_smprintf(errString[EQUIV_LOOP],
1167 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1168 goto loser;
1170 _this->platforms[i].equiv = &_this->platforms[j];
1171 break;
1174 if(_this->platforms[i].equiv == NULL) {
1175 errStr = PR_smprintf(errString[BOGUS_EQUIV],
1176 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1177 goto loser;
1183 // Now the intelligent pass, which will also detect loops.
1184 // We will send two pointers through the linked list of equivalent
1185 // platforms. Both start with the current node. "first" traverses
1186 // two nodes for each iteration. "second" lags behind, only traversing
1187 // one node per iteration. Eventually one of two things will happen:
1188 // first will hit the end of the list (a platform that doesn't use
1189 // an equivalency), or first will equal second if there is a loop.
1191 for(i=0; i < _this->numPlatforms; i++) {
1192 if(_this->platforms[i].usesEquiv) {
1193 second = _this->platforms[i].equiv;
1194 if(!second->usesEquiv) {
1195 /* The first link is the terminal node */
1196 continue;
1198 first = second->equiv;
1199 while(first->usesEquiv) {
1200 if(first == second) {
1201 errStr = PR_smprintf(errString[EQUIV_LOOP],
1202 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1203 goto loser;
1205 first = first->equiv;
1206 if(!first->usesEquiv) {
1207 break;
1209 if(first == second) {
1210 errStr = PR_smprintf(errString[EQUIV_LOOP],
1211 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1212 goto loser;
1214 second = second->equiv;
1215 first = first->equiv;
1217 _this->platforms[i].equiv = first;
1221 loser:
1222 if(iter) {
1223 Pk11Install_ListIter_delete(iter);
1224 PR_Free(iter);
1225 iter = NULL;
1227 if(subiter) {
1228 Pk11Install_ListIter_delete(subiter);
1229 PR_Free(subiter);
1230 subiter = NULL;
1232 return errStr;
1236 //////////////////////////////////////////////////////////////////////////
1237 // Method: GetBestPlatform
1238 // Class: Pk11Install_Info
1239 // Takes: char *myPlatform, the platform we are currently running
1240 // on.
1242 Pk11Install_Platform*
1243 Pk11Install_Info_GetBestPlatform(Pk11Install_Info* _this, char *myPlatform)
1245 Pk11Install_PlatformName plat;
1246 char *errStr;
1247 int i, j;
1249 errStr=NULL;
1251 Pk11Install_PlatformName_init(&plat);
1252 if( (errStr=Pk11Install_PlatformName_Generate(&plat, myPlatform)) ) {
1253 PR_smprintf_free(errStr);
1254 return NULL;
1257 /* First try real platforms */
1258 for(i=0; i < _this->numPlatforms; i++) {
1259 if(Pk11Install_PlatformName_equal(&_this->platforms[i].name,&plat)) {
1260 if(_this->platforms[i].equiv) {
1261 return _this->platforms[i].equiv;
1263 else {
1264 return &_this->platforms[i];
1269 /* Now try forward compatible platforms */
1270 for(i=0; i < _this->numForwardCompatible; i++) {
1271 if(Pk11Install_PlatformName_lteq(&_this->forwardCompatible[i],&plat)) {
1272 break;
1275 if(i == _this->numForwardCompatible) {
1276 return NULL;
1279 /* Got a forward compatible name, find the actual platform. */
1280 for(j=0; j < _this->numPlatforms; j++) {
1281 if(Pk11Install_PlatformName_equal(&_this->platforms[j].name,
1282 &_this->forwardCompatible[i])) {
1283 if(_this->platforms[j].equiv) {
1284 return _this->platforms[j].equiv;
1285 } else {
1286 return &_this->platforms[j];
1291 return NULL;
1295 //////////////////////////////////////////////////////////////////////////
1296 // Method: Print
1297 // Class: Pk11Install_Info
1299 void
1300 Pk11Install_Info_Print(Pk11Install_Info* _this, int pad)
1302 int i;
1304 PAD(pad); printf("Forward Compatible:\n");
1305 for(i = 0; i < _this->numForwardCompatible; i++) {
1306 Pk11Install_PlatformName_Print(&_this->forwardCompatible[i],pad+PADINC);
1307 PAD(pad); printf("-------------------\n");
1309 PAD(pad); printf("Platforms:\n");
1310 for( i = 0; i < _this->numPlatforms; i++) {
1311 Pk11Install_Platform_Print(&_this->platforms[i],pad+PADINC);
1312 PAD(pad); printf("-------------------\n");
1317 //////////////////////////////////////////////////////////////////////////
1319 static char*
1320 PR_Strdup(const char* str)
1322 char *tmp;
1323 tmp = (char*) PR_Malloc((unsigned int)(strlen(str)+1));
1324 strcpy(tmp, str);
1325 return tmp;
1328 /* The global value list, the top of the tree */
1329 Pk11Install_ValueList* Pk11Install_valueList=NULL;
1331 /****************************************************************************/
1332 void
1333 Pk11Install_ValueList_AddItem(Pk11Install_ValueList* _this,
1334 Pk11Install_Value *item)
1336 _this->numItems++;
1337 if (item->type == STRING_VALUE) {
1338 _this->numStrings++;
1339 } else {
1340 _this->numPairs++;
1342 item->next = _this->head;
1343 _this->head = item;
1346 /****************************************************************************/
1347 Pk11Install_ListIter*
1348 Pk11Install_ListIter_new_default()
1350 Pk11Install_ListIter* new_this;
1351 new_this = (Pk11Install_ListIter*)
1352 PR_Malloc(sizeof(Pk11Install_ListIter));
1353 Pk11Install_ListIter_init(new_this);
1354 return new_this;
1357 /****************************************************************************/
1358 void
1359 Pk11Install_ListIter_init(Pk11Install_ListIter* _this)
1361 _this->list = NULL;
1362 _this->current = NULL;
1365 /****************************************************************************/
1366 Pk11Install_ListIter*
1367 Pk11Install_ListIter_new(const Pk11Install_ValueList *_list)
1369 Pk11Install_ListIter* new_this;
1370 new_this = (Pk11Install_ListIter*)
1371 PR_Malloc(sizeof(Pk11Install_ListIter));
1372 new_this->list = _list;
1373 new_this->current = _list->head;
1374 return new_this;
1377 /****************************************************************************/
1378 void
1379 Pk11Install_ListIter_delete(Pk11Install_ListIter* _this)
1381 _this->list=NULL;
1382 _this->current=NULL;
1385 /****************************************************************************/
1386 void
1387 Pk11Install_ListIter_reset(Pk11Install_ListIter* _this)
1389 if(_this->list) {
1390 _this->current = _this->list->head;
1394 /*************************************************************************/
1395 Pk11Install_Value*
1396 Pk11Install_ListIter_nextItem(Pk11Install_ListIter* _this)
1398 if(_this->current) {
1399 _this->current = _this->current->next;
1402 return _this->current;
1405 /****************************************************************************/
1406 Pk11Install_ValueList*
1407 Pk11Install_ValueList_new()
1409 Pk11Install_ValueList* new_this;
1410 new_this = (Pk11Install_ValueList*)
1411 PR_Malloc(sizeof(Pk11Install_ValueList));
1412 new_this->numItems = 0;
1413 new_this->numPairs = 0;
1414 new_this->numStrings = 0;
1415 new_this->head = NULL;
1416 return new_this;
1419 /****************************************************************************/
1420 void
1421 Pk11Install_ValueList_delete(Pk11Install_ValueList* _this)
1424 Pk11Install_Value *tmp;
1425 Pk11Install_Value *list;
1426 list = _this->head;
1428 while(list != NULL) {
1429 tmp = list;
1430 list = list->next;
1431 PR_Free(tmp);
1433 PR_Free(_this);
1436 /****************************************************************************/
1437 Pk11Install_Value*
1438 Pk11Install_Value_new_default()
1440 Pk11Install_Value* new_this;
1441 new_this = (Pk11Install_Value*)PR_Malloc(sizeof(Pk11Install_Value));
1442 new_this->type = STRING_VALUE;
1443 new_this->string = NULL;
1444 new_this->pair = NULL;
1445 new_this->next = NULL;
1446 return new_this;
1449 /****************************************************************************/
1450 Pk11Install_Value*
1451 Pk11Install_Value_new(ValueType _type, Pk11Install_Pointer ptr)
1453 Pk11Install_Value* new_this;
1454 new_this = Pk11Install_Value_new_default();
1455 new_this->type = _type;
1456 if(_type == STRING_VALUE) {
1457 new_this->pair = NULL;
1458 new_this->string = ptr.string;
1459 } else {
1460 new_this->string = NULL;
1461 new_this->pair = ptr.pair;
1463 return new_this;
1466 /****************************************************************************/
1467 void
1468 Pk11Install_Value_delete(Pk11Install_Value* _this)
1470 if(_this->type == STRING_VALUE) {
1471 PR_Free(_this->string);
1472 } else {
1473 PR_Free(_this->pair);
1477 /****************************************************************************/
1478 Pk11Install_Pair*
1479 Pk11Install_Pair_new_default()
1481 return Pk11Install_Pair_new(NULL,NULL);
1484 /****************************************************************************/
1485 Pk11Install_Pair*
1486 Pk11Install_Pair_new(char *_key, Pk11Install_ValueList *_list)
1488 Pk11Install_Pair* new_this;
1489 new_this = (Pk11Install_Pair*)PR_Malloc(sizeof(Pk11Install_Pair));
1490 new_this->key = _key;
1491 new_this->list = _list;
1492 return new_this;
1495 /****************************************************************************/
1496 void
1497 Pk11Install_Pair_delete(Pk11Install_Pair* _this)
1499 PR_Free(_this->key);
1500 Pk11Install_ValueList_delete(_this->list);
1501 PR_Free(_this->list);
1504 /*************************************************************************/
1505 void
1506 Pk11Install_Pair_Print(Pk11Install_Pair* _this, int pad)
1508 while (_this) {
1509 /*PAD(pad); printf("**Pair\n");
1510 PAD(pad); printf("***Key====\n");*/
1511 PAD(pad); printf("%s {\n", _this->key);
1512 /*PAD(pad); printf("====\n");*/
1513 /*PAD(pad); printf("***ValueList\n");*/
1514 Pk11Install_ValueList_Print(_this->list,pad+PADINC);
1515 PAD(pad); printf("}\n");
1519 /*************************************************************************/
1520 void
1521 Pk11Install_ValueList_Print(Pk11Install_ValueList* _this, int pad)
1523 Pk11Install_Value *v;
1525 /*PAD(pad);printf("**Value List**\n");*/
1526 for(v = _this->head; v != NULL; v=v->next) {
1527 Pk11Install_Value_Print(v,pad);
1531 /*************************************************************************/
1532 void
1533 Pk11Install_Value_Print(Pk11Install_Value* _this, int pad)
1535 /*PAD(pad); printf("**Value, type=%s\n",
1536 type==STRING_VALUE ? "string" : "pair");*/
1537 if(_this->type==STRING_VALUE) {
1538 /*PAD(pad+PADINC); printf("====\n");*/
1539 PAD(pad); printf("%s\n", _this->string);
1540 /*PAD(pad+PADINC); printf("====\n");*/
1541 } else {
1542 Pk11Install_Pair_Print(_this->pair,pad+PADINC);