Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "install-ds.h"
6 #include <prmem.h>
7 #include <plstr.h>
8 #include <prprf.h>
9 #include <string.h>
11 #define PORT_Strcasecmp PL_strcasecmp
13 #define MODULE_FILE_STRING "ModuleFile"
14 #define MODULE_NAME_STRING "ModuleName"
15 #define MECH_FLAGS_STRING "DefaultMechanismFlags"
16 #define CIPHER_FLAGS_STRING "DefaultCipherFlags"
17 #define FILES_STRING "Files"
18 #define FORWARD_COMPATIBLE_STRING "ForwardCompatible"
19 #define PLATFORMS_STRING "Platforms"
20 #define RELATIVE_DIR_STRING "RelativePath"
21 #define ABSOLUTE_DIR_STRING "AbsolutePath"
22 #define FILE_PERMISSIONS_STRING "FilePermissions"
23 #define EQUIVALENT_PLATFORM_STRING "EquivalentPlatform"
24 #define EXECUTABLE_STRING "Executable"
26 #define DEFAULT_PERMISSIONS 0777
28 #define PLATFORM_SEPARATOR_CHAR ':'
30 /* Error codes */
31 enum {
32 BOGUS_RELATIVE_DIR=0,
33 BOGUS_ABSOLUTE_DIR,
34 BOGUS_FILE_PERMISSIONS,
35 NO_RELATIVE_DIR,
36 NO_ABSOLUTE_DIR,
37 EMPTY_PLATFORM_STRING,
38 BOGUS_PLATFORM_STRING,
39 REPEAT_MODULE_FILE,
40 REPEAT_MODULE_NAME,
41 BOGUS_MODULE_FILE,
42 BOGUS_MODULE_NAME,
43 REPEAT_MECH,
44 BOGUS_MECH_FLAGS,
45 REPEAT_CIPHER,
46 BOGUS_CIPHER_FLAGS,
47 REPEAT_FILES,
48 REPEAT_EQUIV,
49 BOGUS_EQUIV,
50 EQUIV_TOO_MUCH_INFO,
51 NO_FILES,
52 NO_MODULE_FILE,
53 NO_MODULE_NAME,
54 NO_PLATFORMS,
55 EQUIV_LOOP,
56 UNKNOWN_MODULE_FILE
57 };
59 /* Indexed by the above error codes */
60 static const char *errString[] = {
61 "%s: Invalid relative directory",
62 "%s: Invalid absolute directory",
63 "%s: Invalid file permissions",
64 "%s: No relative directory specified",
65 "%s: No absolute directory specified",
66 "Empty string given for platform name",
67 "%s: invalid platform string",
68 "More than one ModuleFile entry given for platform %s",
69 "More than one ModuleName entry given for platform %s",
70 "Invalid ModuleFile specification for platform %s",
71 "Invalid ModuleName specification for platform %s",
72 "More than one DefaultMechanismFlags entry given for platform %s",
73 "Invalid DefaultMechanismFlags specification for platform %s",
74 "More than one DefaultCipherFlags entry given for platform %s",
75 "Invalid DefaultCipherFlags entry given for platform %s",
76 "More than one Files entry given for platform %s",
77 "More than one EquivalentPlatform entry given for platform %s",
78 "Invalid EquivalentPlatform specification for platform %s",
79 "Module %s uses an EquivalentPlatform but also specifies its own"
80 " information",
81 "No Files specification in module %s",
82 "No ModuleFile specification in module %s",
83 "No ModuleName specification in module %s",
84 "No Platforms specification in installer script",
85 "Platform %s has an equivalency loop",
86 "Module file \"%s\" in platform \"%s\" does not exist"
87 };
89 static char* PR_Strdup(const char* str);
91 #define PAD(x) {int i; for(i=0;i<x;i++) printf(" ");}
92 #define PADINC 4
94 Pk11Install_File*
95 Pk11Install_File_new()
96 {
97 Pk11Install_File* new_this;
98 new_this = (Pk11Install_File*)PR_Malloc(sizeof(Pk11Install_File));
99 Pk11Install_File_init(new_this);
100 return new_this;
101 }
103 void
104 Pk11Install_File_init(Pk11Install_File* _this)
105 {
106 _this->jarPath=NULL;
107 _this->relativePath=NULL;
108 _this->absolutePath=NULL;
109 _this->executable=PR_FALSE;
110 _this->permissions=0;
111 }
113 /*
114 //////////////////////////////////////////////////////////////////////////
115 // Method: ~Pk11Install_File
116 // Class: Pk11Install_File
117 // Notes: Destructor.
118 */
119 void
120 Pk11Install_File_delete(Pk11Install_File* _this)
121 {
122 Pk11Install_File_Cleanup(_this);
123 }
125 /*
126 //////////////////////////////////////////////////////////////////////////
127 // Method: Cleanup
128 // Class: Pk11Install_File
129 */
130 void
131 Pk11Install_File_Cleanup(Pk11Install_File* _this)
132 {
133 if(_this->jarPath) {
134 PR_Free(_this->jarPath);
135 _this->jarPath = NULL;
136 }
137 if(_this->relativePath) {
138 PR_Free(_this->relativePath);
139 _this->relativePath = NULL;
140 }
141 if(_this->absolutePath) {
142 PR_Free(_this->absolutePath);
143 _this->absolutePath = NULL;
144 }
146 _this->permissions = 0;
147 _this->executable = PR_FALSE;
148 }
150 /*
151 //////////////////////////////////////////////////////////////////////////
152 // Method: Generate
153 // Class: Pk11Install_File
154 // Notes: Creates a file data structure from a syntax tree.
155 // Returns: NULL for success, otherwise an error message.
156 */
157 char*
158 Pk11Install_File_Generate(Pk11Install_File* _this,
159 const Pk11Install_Pair *pair)
160 {
161 Pk11Install_ListIter *iter;
162 Pk11Install_Value *val;
163 Pk11Install_Pair *subpair;
164 Pk11Install_ListIter *subiter;
165 Pk11Install_Value *subval;
166 char* errStr;
167 char *endp;
168 PRBool gotPerms;
170 iter=NULL;
171 subiter=NULL;
172 errStr=NULL;
173 gotPerms=PR_FALSE;
175 /* Clear out old values */
176 Pk11Install_File_Cleanup(_this);
178 _this->jarPath = PR_Strdup(pair->key);
180 /* Go through all the pairs under this file heading */
181 iter = Pk11Install_ListIter_new(pair->list);
182 for( ; (val = iter->current); Pk11Install_ListIter_nextItem(iter)) {
183 if(val->type == PAIR_VALUE) {
184 subpair = val->pair;
186 /* Relative directory */
187 if(!PORT_Strcasecmp(subpair->key, RELATIVE_DIR_STRING)) {
188 subiter = Pk11Install_ListIter_new(subpair->list);
189 subval = subiter->current;
190 if(!subval || (subval->type != STRING_VALUE)){
191 errStr = PR_smprintf(errString[BOGUS_RELATIVE_DIR],
192 _this->jarPath);
193 goto loser;
194 }
195 _this->relativePath = PR_Strdup(subval->string);
196 Pk11Install_ListIter_delete(subiter);
197 subiter = NULL;
199 /* Absolute directory */
200 } else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
201 subiter = Pk11Install_ListIter_new(subpair->list);
202 subval = subiter->current;
203 if(!subval || (subval->type != STRING_VALUE)){
204 errStr = PR_smprintf(errString[BOGUS_ABSOLUTE_DIR],
205 _this->jarPath);
206 goto loser;
207 }
208 _this->absolutePath = PR_Strdup(subval->string);
209 Pk11Install_ListIter_delete(subiter);
210 subiter = NULL;
212 /* file permissions */
213 } else if( !PORT_Strcasecmp(subpair->key,
214 FILE_PERMISSIONS_STRING)) {
215 subiter = Pk11Install_ListIter_new(subpair->list);
216 subval = subiter->current;
217 if(!subval || (subval->type != STRING_VALUE) ||
218 !subval->string || !subval->string[0]){
219 errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
220 _this->jarPath);
221 goto loser;
222 }
223 _this->permissions = (int) strtol(subval->string, &endp, 8);
224 if(*endp != '\0') {
225 errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
226 _this->jarPath);
227 goto loser;
228 }
229 gotPerms = PR_TRUE;
230 Pk11Install_ListIter_delete(subiter);
231 subiter = NULL;
232 }
233 } else {
234 if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
235 _this->executable = PR_TRUE;
236 }
237 }
238 }
240 /* Default permission value */
241 if(!gotPerms) {
242 _this->permissions = DEFAULT_PERMISSIONS;
243 }
245 /* Make sure we got all the information */
246 if(!_this->relativePath && !_this->absolutePath) {
247 errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath);
248 goto loser;
249 }
250 #if 0
251 if(!_this->relativePath ) {
252 errStr = PR_smprintf(errString[NO_RELATIVE_DIR], _this->jarPath);
253 goto loser;
254 }
255 if(!_this->absolutePath) {
256 errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath);
257 goto loser;
258 }
259 #endif
261 loser:
262 if(iter) {
263 Pk11Install_ListIter_delete(iter);
264 PR_Free(iter);
265 }
266 if(subiter) {
267 Pk11Install_ListIter_delete(subiter);
268 PR_Free(subiter);
269 }
270 return errStr;
271 }
273 /*
274 //////////////////////////////////////////////////////////////////////////
275 // Method: Print
276 // Class: Pk11Install_File
277 */
278 void
279 Pk11Install_File_Print(Pk11Install_File* _this, int pad)
280 {
281 PAD(pad); printf("jarPath: %s\n",
282 _this->jarPath ? _this->jarPath : "<NULL>");
283 PAD(pad); printf("relativePath: %s\n",
284 _this->relativePath ? _this->relativePath: "<NULL>");
285 PAD(pad); printf("absolutePath: %s\n",
286 _this->absolutePath ? _this->absolutePath: "<NULL>");
287 PAD(pad); printf("permissions: %o\n", _this->permissions);
288 }
290 Pk11Install_PlatformName*
291 Pk11Install_PlatformName_new()
292 {
293 Pk11Install_PlatformName* new_this;
294 new_this = (Pk11Install_PlatformName*)
295 PR_Malloc(sizeof(Pk11Install_PlatformName));
296 Pk11Install_PlatformName_init(new_this);
297 return new_this;
298 }
300 void
301 Pk11Install_PlatformName_init(Pk11Install_PlatformName* _this)
302 {
303 _this->OS = NULL;
304 _this->verString = NULL;
305 _this->numDigits = 0;
306 _this->arch = NULL;
307 }
309 /*
310 //////////////////////////////////////////////////////////////////////////
311 // Method: ~Pk11Install_PlatformName
312 // Class: Pk11Install_PlatformName
313 */
314 void
315 Pk11Install_PlatformName_delete(Pk11Install_PlatformName* _this)
316 {
317 Pk11Install_PlatformName_Cleanup(_this);
318 }
320 /*
321 //////////////////////////////////////////////////////////////////////////
322 // Method: Cleanup
323 // Class: Pk11Install_PlatformName
324 */
325 void
326 Pk11Install_PlatformName_Cleanup(Pk11Install_PlatformName* _this)
327 {
328 if(_this->OS) {
329 PR_Free(_this->OS);
330 _this->OS = NULL;
331 }
332 if(_this->verString) {
333 int i;
334 for (i=0; i<_this->numDigits; i++) {
335 PR_Free(_this->verString[i]);
336 }
337 PR_Free(_this->verString);
338 _this->verString = NULL;
339 }
340 if(_this->arch) {
341 PR_Free(_this->arch);
342 _this->arch = NULL;
343 }
344 _this->numDigits = 0;
345 }
347 /*
348 //////////////////////////////////////////////////////////////////////////
349 // Method: Generate
350 // Class: Pk11Install_PlatformName
351 // Notes: Extracts the information from a platform string.
352 */
353 char*
354 Pk11Install_PlatformName_Generate(Pk11Install_PlatformName* _this,
355 const char *str)
356 {
357 char *errStr;
358 char *copy;
359 char *end, *start; /* start and end of a section (OS, version, arch)*/
360 char *pend, *pstart; /* start and end of one portion of version*/
361 char *endp; /* used by strtol*/
362 int periods, i;
364 errStr=NULL;
365 copy=NULL;
367 if(!str) {
368 errStr = PR_smprintf(errString[EMPTY_PLATFORM_STRING]);
369 goto loser;
370 }
371 copy = PR_Strdup(str);
373 /*
374 // Get the OS
375 */
376 end = strchr(copy, PLATFORM_SEPARATOR_CHAR);
377 if(!end || end==copy) {
378 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
379 goto loser;
380 }
381 *end = '\0';
383 _this->OS = PR_Strdup(copy);
385 /*
386 // Get the digits of the version of form: x.x.x (arbitrary number of digits)
387 */
389 start = end+1;
390 end = strchr(start, PLATFORM_SEPARATOR_CHAR);
391 if(!end) {
392 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
393 goto loser;
394 }
395 *end = '\0';
397 if(end!=start) {
398 /* Find out how many periods*/
399 periods = 0;
400 pstart = start;
401 while( (pend=strchr(pstart, '.')) ) {
402 periods++;
403 pstart = pend+1;
404 }
405 _this->numDigits= 1+ periods;
406 _this->verString = (char**)PR_Malloc(sizeof(char*)*_this->numDigits);
408 pstart = start;
409 i = 0;
410 /* Get the digits before each period*/
411 while( (pend=strchr(pstart, '.')) ) {
412 if(pend == pstart) {
413 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
414 goto loser;
415 }
416 *pend = '\0';
417 _this->verString[i] = PR_Strdup(pstart);
418 endp = pend;
419 if(endp==pstart || (*endp != '\0')) {
420 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
421 goto loser;
422 }
423 pstart = pend+1;
424 i++;
425 }
426 /* Last digit comes after the last period*/
427 if(*pstart == '\0') {
428 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
429 goto loser;
430 }
431 _this->verString[i] = PR_Strdup(pstart);
432 /*
433 if(endp==pstart || (*endp != '\0')) {
434 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
435 goto loser;
436 }
437 */
438 } else {
439 _this->verString = NULL;
440 _this->numDigits = 0;
441 }
443 /*
444 // Get the architecture
445 */
446 start = end+1;
447 if( strchr(start, PLATFORM_SEPARATOR_CHAR) ) {
448 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
449 goto loser;
450 }
451 _this->arch = PR_Strdup(start);
453 if(copy) {
454 PR_Free(copy);
455 }
456 return NULL;
457 loser:
458 if(_this->OS) {
459 PR_Free(_this->OS);
460 _this->OS = NULL;
461 }
462 if(_this->verString) {
463 for (i=0; i<_this->numDigits; i++) {
464 PR_Free(_this->verString[i]);
465 }
466 PR_Free(_this->verString);
467 _this->verString = NULL;
468 }
469 _this->numDigits = 0;
470 if(_this->arch) {
471 PR_Free(_this->arch);
472 _this->arch = NULL;
473 }
475 return errStr;
476 }
478 /*
479 //////////////////////////////////////////////////////////////////////////
480 // Method: operator ==
481 // Class: Pk11Install_PlatformName
482 // Returns: PR_TRUE if the platform have the same OS, arch, and version
483 */
484 PRBool
485 Pk11Install_PlatformName_equal(Pk11Install_PlatformName* _this,
486 Pk11Install_PlatformName* cmp)
487 {
488 int i;
490 if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) {
491 return PR_FALSE;
492 }
494 if( PORT_Strcasecmp(_this->OS, cmp->OS) ||
495 PORT_Strcasecmp(_this->arch, cmp->arch) ||
496 _this->numDigits != cmp->numDigits ) {
497 return PR_FALSE;
498 }
500 for(i=0; i < _this->numDigits; i++) {
501 if(PORT_Strcasecmp(_this->verString[i], cmp->verString[i])) {
502 return PR_FALSE;
503 }
504 }
505 return PR_TRUE;
506 }
508 /*
509 //////////////////////////////////////////////////////////////////////////
510 // Method: operator <=
511 // Class: Pk11Install_PlatformName
512 // Returns: PR_TRUE if the platform have the same OS and arch and a lower
513 // or equal release.
514 */
515 PRBool
516 Pk11Install_PlatformName_lteq(Pk11Install_PlatformName* _this,
517 Pk11Install_PlatformName* cmp)
518 {
519 return (Pk11Install_PlatformName_equal(_this,cmp) ||
520 Pk11Install_PlatformName_lt(_this,cmp)) ? PR_TRUE : PR_FALSE;
521 }
523 /*
524 //////////////////////////////////////////////////////////////////////////
525 // Method: operator <
526 // Class: Pk11Install_PlatformName
527 // Returns: PR_TRUE if the platform have the same OS and arch and a greater
528 // release.
529 */
530 PRBool
531 Pk11Install_PlatformName_lt(Pk11Install_PlatformName* _this,
532 Pk11Install_PlatformName* cmp)
533 {
534 int i, scmp;
536 if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) {
537 return PR_FALSE;
538 }
540 if( PORT_Strcasecmp(_this->OS, cmp->OS) ) {
541 return PR_FALSE;
542 }
543 if( PORT_Strcasecmp(_this->arch, cmp->arch) ) {
544 return PR_FALSE;
545 }
547 for(i=0; (i < _this->numDigits) && (i < cmp->numDigits); i++) {
548 scmp = PORT_Strcasecmp(_this->verString[i], cmp->verString[i]);
549 if (scmp > 0) {
550 return PR_FALSE;
551 } else if (scmp < 0) {
552 return PR_TRUE;
553 }
554 }
555 /* All the digits they have in common are the same. */
556 if(_this->numDigits < cmp->numDigits) {
557 return PR_TRUE;
558 }
560 return PR_FALSE;
561 }
563 /*
564 //////////////////////////////////////////////////////////////////////////
565 // Method: GetString
566 // Class: Pk11Install_PlatformName
567 // Returns: String composed of OS, release, and architecture separated
568 // by the separator char. Memory is allocated by this function
569 // but is the responsibility of the caller to de-allocate.
570 */
571 char*
572 Pk11Install_PlatformName_GetString(Pk11Install_PlatformName* _this)
573 {
574 char *ret;
575 char *ver;
576 char *OS_;
577 char *arch_;
579 OS_=NULL;
580 arch_=NULL;
582 OS_ = _this->OS ? _this->OS : "";
583 arch_ = _this->arch ? _this->arch : "";
585 ver = Pk11Install_PlatformName_GetVerString(_this);
586 ret = PR_smprintf("%s%c%s%c%s", OS_, PLATFORM_SEPARATOR_CHAR, ver,
587 PLATFORM_SEPARATOR_CHAR, arch_);
589 PR_Free(ver);
591 return ret;
592 }
594 /*
595 //////////////////////////////////////////////////////////////////////////
596 // Method: GetVerString
597 // Class: Pk11Install_PlatformName
598 // Returns: The version string for this platform, in the form x.x.x with an
599 // arbitrary number of digits. Memory allocated by function,
600 // must be de-allocated by caller.
601 */
602 char*
603 Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this)
604 {
605 char *tmp;
606 char *ret;
607 int i;
608 char buf[80];
610 tmp = (char*)PR_Malloc(80*_this->numDigits+1);
611 tmp[0] = '\0';
613 for(i=0; i < _this->numDigits-1; i++) {
614 sprintf(buf, "%s.", _this->verString[i]);
615 strcat(tmp, buf);
616 }
617 if(i < _this->numDigits) {
618 sprintf(buf, "%s", _this->verString[i]);
619 strcat(tmp, buf);
620 }
622 ret = PR_Strdup(tmp);
623 free(tmp);
625 return ret;
626 }
628 /*
629 //////////////////////////////////////////////////////////////////////////
630 // Method: Print
631 // Class: Pk11Install_PlatformName
632 */
633 void
634 Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad)
635 {
636 PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>");
637 PAD(pad); printf("Digits: ");
638 if(_this->numDigits == 0) {
639 printf("None\n");
640 } else {
641 printf("%s\n", Pk11Install_PlatformName_GetVerString(_this));
642 }
643 PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>");
644 }
646 Pk11Install_Platform*
647 Pk11Install_Platform_new()
648 {
649 Pk11Install_Platform* new_this;
650 new_this = (Pk11Install_Platform*)PR_Malloc(sizeof(Pk11Install_Platform));
651 Pk11Install_Platform_init(new_this);
652 return new_this;
653 }
655 void
656 Pk11Install_Platform_init(Pk11Install_Platform* _this)
657 {
658 Pk11Install_PlatformName_init(&_this->name);
659 Pk11Install_PlatformName_init(&_this->equivName);
660 _this->equiv = NULL;
661 _this->usesEquiv = PR_FALSE;
662 _this->moduleFile = NULL;
663 _this->moduleName = NULL;
664 _this->modFile = -1;
665 _this->mechFlags = 0;
666 _this->cipherFlags = 0;
667 _this->files = NULL;
668 _this->numFiles = 0;
669 }
671 /*
672 //////////////////////////////////////////////////////////////////////////
673 // Method: ~Pk11Install_Platform
674 // Class: Pk11Install_Platform
675 */
676 void
677 Pk11Install_Platform_delete(Pk11Install_Platform* _this)
678 {
679 Pk11Install_Platform_Cleanup(_this);
680 }
682 /*
683 //////////////////////////////////////////////////////////////////////////
684 // Method: Cleanup
685 // Class: Pk11Install_Platform
686 */
687 void
688 Pk11Install_Platform_Cleanup(Pk11Install_Platform* _this)
689 {
690 int i;
691 if(_this->moduleFile) {
692 PR_Free(_this->moduleFile);
693 _this->moduleFile = NULL;
694 }
695 if(_this->moduleName) {
696 PR_Free(_this->moduleName);
697 _this->moduleName = NULL;
698 }
699 if(_this->files) {
700 for (i=0;i<_this->numFiles;i++) {
701 Pk11Install_File_delete(&_this->files[i]);
702 }
703 PR_Free(_this->files);
704 _this->files = NULL;
705 }
706 _this->equiv = NULL;
707 _this->usesEquiv = PR_FALSE;
708 _this->modFile = -1;
709 _this->numFiles = 0;
710 _this->mechFlags = _this->cipherFlags = 0;
711 }
713 /*
714 //////////////////////////////////////////////////////////////////////////
715 // Method: Generate
716 // Class: Pk11Install_Platform
717 // Notes: Creates a platform data structure from a syntax tree.
718 // Returns: NULL for success, otherwise an error message.
719 */
720 char*
721 Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
722 const Pk11Install_Pair *pair)
723 {
724 char* errStr;
725 char* endptr;
726 char* tmp;
727 int i;
728 Pk11Install_ListIter *iter;
729 Pk11Install_Value *val;
730 Pk11Install_Value *subval;
731 Pk11Install_Pair *subpair;
732 Pk11Install_ListIter *subiter;
733 PRBool gotModuleFile, gotModuleName, gotMech,
734 gotCipher, gotFiles, gotEquiv;
736 errStr=NULL;
737 iter=subiter=NULL;
738 val=subval=NULL;
739 subpair=NULL;
740 gotModuleFile=gotModuleName=gotMech=gotCipher=gotFiles=gotEquiv=PR_FALSE;
741 Pk11Install_Platform_Cleanup(_this);
743 errStr = Pk11Install_PlatformName_Generate(&_this->name,pair->key);
744 if(errStr) {
745 tmp = PR_smprintf("%s: %s", pair->key, errStr);
746 PR_smprintf_free(errStr);
747 errStr = tmp;
748 goto loser;
749 }
751 iter = Pk11Install_ListIter_new(pair->list);
752 for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) {
753 if(val->type==PAIR_VALUE) {
754 subpair = val->pair;
756 if( !PORT_Strcasecmp(subpair->key, MODULE_FILE_STRING)) {
757 if(gotModuleFile) {
758 errStr = PR_smprintf(errString[REPEAT_MODULE_FILE],
759 Pk11Install_PlatformName_GetString(&_this->name));
760 goto loser;
761 }
762 subiter = Pk11Install_ListIter_new(subpair->list);
763 subval = subiter->current;
764 if(!subval || (subval->type != STRING_VALUE)) {
765 errStr = PR_smprintf(errString[BOGUS_MODULE_FILE],
766 Pk11Install_PlatformName_GetString(&_this->name));
767 goto loser;
768 }
769 _this->moduleFile = PR_Strdup(subval->string);
770 Pk11Install_ListIter_delete(subiter);
771 PR_Free(subiter);
772 subiter = NULL;
773 gotModuleFile = PR_TRUE;
774 } else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
775 if(gotModuleName) {
776 errStr = PR_smprintf(errString[REPEAT_MODULE_NAME],
777 Pk11Install_PlatformName_GetString(&_this->name));
778 goto loser;
779 }
780 subiter = Pk11Install_ListIter_new(subpair->list);
781 subval = subiter->current;
782 if(!subval || (subval->type != STRING_VALUE)) {
783 errStr = PR_smprintf(errString[BOGUS_MODULE_NAME],
784 Pk11Install_PlatformName_GetString(&_this->name));
785 goto loser;
786 }
787 _this->moduleName = PR_Strdup(subval->string);
788 Pk11Install_ListIter_delete(subiter);
789 PR_Free(subiter);
790 subiter = NULL;
791 gotModuleName = PR_TRUE;
792 } else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
793 endptr=NULL;
795 if(gotMech) {
796 errStr = PR_smprintf(errString[REPEAT_MECH],
797 Pk11Install_PlatformName_GetString(&_this->name));
798 goto loser;
799 }
800 subiter = Pk11Install_ListIter_new(subpair->list);
801 subval = subiter->current;
802 if(!subval || (subval->type != STRING_VALUE)) {
803 errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS],
804 Pk11Install_PlatformName_GetString(&_this->name));
805 goto loser;
806 }
807 _this->mechFlags = strtol(subval->string, &endptr, 0);
808 if(*endptr!='\0' || (endptr==subval->string) ) {
809 errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS],
810 Pk11Install_PlatformName_GetString(&_this->name));
811 goto loser;
812 }
813 Pk11Install_ListIter_delete(subiter);
814 PR_Free(subiter);
815 subiter=NULL;
816 gotMech = PR_TRUE;
817 } else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
818 endptr=NULL;
820 if(gotCipher) {
821 errStr = PR_smprintf(errString[REPEAT_CIPHER],
822 Pk11Install_PlatformName_GetString(&_this->name));
823 goto loser;
824 }
825 subiter = Pk11Install_ListIter_new(subpair->list);
826 subval = subiter->current;
827 if(!subval || (subval->type != STRING_VALUE)) {
828 errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS],
829 Pk11Install_PlatformName_GetString(&_this->name));
830 goto loser;
831 }
832 _this->cipherFlags = strtol(subval->string, &endptr, 0);
833 if(*endptr!='\0' || (endptr==subval->string) ) {
834 errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS],
835 Pk11Install_PlatformName_GetString(&_this->name));
836 goto loser;
837 }
838 Pk11Install_ListIter_delete(subiter);
839 PR_Free(subiter);
840 subiter=NULL;
841 gotCipher = PR_TRUE;
842 } else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
843 if(gotFiles) {
844 errStr = PR_smprintf(errString[REPEAT_FILES],
845 Pk11Install_PlatformName_GetString(&_this->name));
846 goto loser;
847 }
848 subiter = Pk11Install_ListIter_new(subpair->list);
849 _this->numFiles = subpair->list->numPairs;
850 _this->files = (Pk11Install_File*)
851 PR_Malloc(sizeof(Pk11Install_File)*_this->numFiles);
852 for(i=0; i < _this->numFiles; i++,
853 Pk11Install_ListIter_nextItem(subiter)) {
854 Pk11Install_File_init(&_this->files[i]);
855 val = subiter->current;
856 if(val && (val->type==PAIR_VALUE)) {
857 errStr = Pk11Install_File_Generate(&_this->files[i],val->pair);
858 if(errStr) {
859 tmp = PR_smprintf("%s: %s",
860 Pk11Install_PlatformName_GetString(&_this->name),errStr);
861 PR_smprintf_free(errStr);
862 errStr = tmp;
863 goto loser;
864 }
865 }
866 }
867 gotFiles = PR_TRUE;
868 } else if(!PORT_Strcasecmp(subpair->key,
869 EQUIVALENT_PLATFORM_STRING)) {
870 if(gotEquiv) {
871 errStr = PR_smprintf(errString[REPEAT_EQUIV],
872 Pk11Install_PlatformName_GetString(&_this->name));
873 goto loser;
874 }
875 subiter = Pk11Install_ListIter_new(subpair->list);
876 subval = subiter->current;
877 if(!subval || (subval->type != STRING_VALUE) ) {
878 errStr = PR_smprintf(errString[BOGUS_EQUIV],
879 Pk11Install_PlatformName_GetString(&_this->name));
880 goto loser;
881 }
882 errStr = Pk11Install_PlatformName_Generate(&_this->equivName,
883 subval->string);
884 if(errStr) {
885 tmp = PR_smprintf("%s: %s",
886 Pk11Install_PlatformName_GetString(&_this->name), errStr);
887 tmp = PR_smprintf("%s: %s",
888 Pk11Install_PlatformName_GetString(&_this->name), errStr);
889 PR_smprintf_free(errStr);
890 errStr = tmp;
891 goto loser;
892 }
893 _this->usesEquiv = PR_TRUE;
894 }
895 }
896 }
898 /* Make sure we either have an EquivalentPlatform or all the other info */
899 if(_this->usesEquiv &&
900 (gotFiles || gotModuleFile || gotModuleName || gotMech || gotCipher)) {
901 errStr = PR_smprintf(errString[EQUIV_TOO_MUCH_INFO],
902 Pk11Install_PlatformName_GetString(&_this->name));
903 goto loser;
904 }
905 if(!gotFiles && !_this->usesEquiv) {
906 errStr = PR_smprintf(errString[NO_FILES],
907 Pk11Install_PlatformName_GetString(&_this->name));
908 goto loser;
909 }
910 if(!gotModuleFile && !_this->usesEquiv) {
911 errStr= PR_smprintf(errString[NO_MODULE_FILE],
912 Pk11Install_PlatformName_GetString(&_this->name));
913 goto loser;
914 }
915 if(!gotModuleName && !_this->usesEquiv) {
916 errStr = PR_smprintf(errString[NO_MODULE_NAME],
917 Pk11Install_PlatformName_GetString(&_this->name));
918 goto loser;
919 }
921 /* Point the modFile pointer to the correct file */
922 if(gotModuleFile) {
923 for(i=0; i < _this->numFiles; i++) {
924 if(!PORT_Strcasecmp(_this->moduleFile, _this->files[i].jarPath) ) {
925 _this->modFile = i;
926 break;
927 }
928 }
929 if(_this->modFile==-1) {
930 errStr = PR_smprintf(errString[UNKNOWN_MODULE_FILE],
931 _this->moduleFile,
932 Pk11Install_PlatformName_GetString(&_this->name));
933 goto loser;
934 }
935 }
937 loser:
938 if(iter) {
939 PR_Free(iter);
940 }
941 if(subiter) {
942 PR_Free(subiter);
943 }
944 return errStr;
945 }
947 /*
948 //////////////////////////////////////////////////////////////////////////
949 // Method: Print
950 // Class: Pk11Install_Platform
951 */
952 void
953 Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad)
954 {
955 int i;
957 PAD(pad); printf("Name:\n");
958 Pk11Install_PlatformName_Print(&_this->name,pad+PADINC);
959 PAD(pad); printf("equivName:\n");
960 Pk11Install_PlatformName_Print(&_this->equivName,pad+PADINC);
961 PAD(pad);
962 if(_this->usesEquiv) {
963 printf("Uses equiv, which points to:\n");
964 Pk11Install_Platform_Print(_this->equiv,pad+PADINC);
965 } else {
966 printf("Doesn't use equiv\n");
967 }
968 PAD(pad);
969 printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile
970 : "<NULL>");
971 PAD(pad); printf("mechFlags: %lx\n", _this->mechFlags);
972 PAD(pad); printf("cipherFlags: %lx\n", _this->cipherFlags);
973 PAD(pad); printf("Files:\n");
974 for(i=0; i < _this->numFiles; i++) {
975 Pk11Install_File_Print(&_this->files[i],pad+PADINC);
976 PAD(pad); printf("--------------------\n");
977 }
978 }
980 /*
981 //////////////////////////////////////////////////////////////////////////
982 // Method: Pk11Install_Info
983 // Class: Pk11Install_Info
984 */
985 Pk11Install_Info*
986 Pk11Install_Info_new()
987 {
988 Pk11Install_Info* new_this;
989 new_this = (Pk11Install_Info*)PR_Malloc(sizeof(Pk11Install_Info));
990 Pk11Install_Info_init(new_this);
991 return new_this;
992 }
994 void
995 Pk11Install_Info_init(Pk11Install_Info* _this)
996 {
997 _this->platforms = NULL;
998 _this->numPlatforms = 0;
999 _this->forwardCompatible = NULL;
1000 _this->numForwardCompatible = 0;
1001 }
1003 /*
1004 //////////////////////////////////////////////////////////////////////////
1005 // Method: ~Pk11Install_Info
1006 // Class: Pk11Install_Info
1007 */
1008 void
1009 Pk11Install_Info_delete(Pk11Install_Info* _this)
1010 {
1011 Pk11Install_Info_Cleanup(_this);
1012 }
1014 /*
1015 //////////////////////////////////////////////////////////////////////////
1016 // Method: Cleanup
1017 // Class: Pk11Install_Info
1018 */
1019 void
1020 Pk11Install_Info_Cleanup(Pk11Install_Info* _this)
1021 {
1022 int i;
1023 if(_this->platforms) {
1024 for (i=0;i<_this->numPlatforms;i++) {
1025 Pk11Install_Platform_delete(&_this->platforms[i]);
1026 }
1027 PR_Free(&_this->platforms);
1028 _this->platforms = NULL;
1029 _this->numPlatforms = 0;
1030 }
1032 if(_this->forwardCompatible) {
1033 for (i=0;i<_this->numForwardCompatible;i++) {
1034 Pk11Install_PlatformName_delete(&_this->forwardCompatible[i]);
1035 }
1036 PR_Free(&_this->forwardCompatible);
1037 _this->numForwardCompatible = 0;
1038 }
1039 }
1041 /*
1042 //////////////////////////////////////////////////////////////////////////
1043 // Method: Generate
1044 // Class: Pk11Install_Info
1045 // Takes: Pk11Install_ValueList *list, the top-level list
1046 // resulting from parsing an installer file.
1047 // Returns: char*, NULL if successful, otherwise an error string.
1048 // Caller is responsible for freeing memory.
1049 */
1050 char*
1051 Pk11Install_Info_Generate(Pk11Install_Info* _this,
1052 const Pk11Install_ValueList *list)
1053 {
1054 char *errStr;
1055 Pk11Install_ListIter *iter;
1056 Pk11Install_Value *val;
1057 Pk11Install_Pair *pair;
1058 Pk11Install_ListIter *subiter;
1059 Pk11Install_Value *subval;
1060 Pk11Install_Platform *first, *second;
1061 int i, j;
1063 errStr=NULL;
1064 iter=subiter=NULL;
1065 Pk11Install_Info_Cleanup(_this);
1067 iter = Pk11Install_ListIter_new(list);
1068 for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) {
1069 if(val->type == PAIR_VALUE) {
1070 pair = val->pair;
1072 if(!PORT_Strcasecmp(pair->key, FORWARD_COMPATIBLE_STRING)) {
1073 subiter = Pk11Install_ListIter_new(pair->list);
1074 _this->numForwardCompatible = pair->list->numStrings;
1075 _this->forwardCompatible = (Pk11Install_PlatformName*)
1076 PR_Malloc(sizeof(Pk11Install_PlatformName)*
1077 _this->numForwardCompatible);
1078 for(i=0; i < _this->numForwardCompatible; i++,
1079 Pk11Install_ListIter_nextItem(subiter)) {
1080 subval = subiter->current;
1081 if(subval->type == STRING_VALUE) {
1082 errStr = Pk11Install_PlatformName_Generate(
1083 &_this->forwardCompatible[i], subval->string);
1084 if(errStr) {
1085 goto loser;
1086 }
1087 }
1088 }
1089 Pk11Install_ListIter_delete(subiter);
1090 PR_Free(subiter);
1091 subiter = NULL;
1092 } else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
1093 subiter = Pk11Install_ListIter_new(pair->list);
1094 _this->numPlatforms = pair->list->numPairs;
1095 _this->platforms = (Pk11Install_Platform*)
1096 PR_Malloc(sizeof(Pk11Install_Platform)*
1097 _this->numPlatforms);
1098 for(i=0; i < _this->numPlatforms; i++,
1099 Pk11Install_ListIter_nextItem(subiter)) {
1100 Pk11Install_Platform_init(&_this->platforms[i]);
1101 subval = subiter->current;
1102 if(subval->type == PAIR_VALUE) {
1103 errStr = Pk11Install_Platform_Generate(&_this->platforms[i],subval->pair);
1104 if(errStr) {
1105 goto loser;
1106 }
1107 }
1108 }
1109 Pk11Install_ListIter_delete(subiter);
1110 PR_Free(subiter);
1111 subiter = NULL;
1112 }
1113 }
1114 }
1116 if(_this->numPlatforms == 0) {
1117 errStr = PR_smprintf(errString[NO_PLATFORMS]);
1118 goto loser;
1119 }
1121 /*
1122 //
1123 // Now process equivalent platforms
1124 //
1126 // First the naive pass
1127 */
1128 for(i=0; i < _this->numPlatforms; i++) {
1129 if(_this->platforms[i].usesEquiv) {
1130 _this->platforms[i].equiv = NULL;
1131 for(j=0; j < _this->numPlatforms; j++) {
1132 if (Pk11Install_PlatformName_equal(&_this->platforms[i].equivName,
1133 &_this->platforms[j].name)) {
1134 if(i==j) {
1135 errStr = PR_smprintf(errString[EQUIV_LOOP],
1136 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1137 goto loser;
1138 }
1139 _this->platforms[i].equiv = &_this->platforms[j];
1140 break;
1141 }
1142 }
1143 if(_this->platforms[i].equiv == NULL) {
1144 errStr = PR_smprintf(errString[BOGUS_EQUIV],
1145 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1146 goto loser;
1147 }
1148 }
1149 }
1151 /*
1152 // Now the intelligent pass, which will also detect loops.
1153 // We will send two pointers through the linked list of equivalent
1154 // platforms. Both start with the current node. "first" traverses
1155 // two nodes for each iteration. "second" lags behind, only traversing
1156 // one node per iteration. Eventually one of two things will happen:
1157 // first will hit the end of the list (a platform that doesn't use
1158 // an equivalency), or first will equal second if there is a loop.
1159 */
1160 for(i=0; i < _this->numPlatforms; i++) {
1161 if(_this->platforms[i].usesEquiv) {
1162 second = _this->platforms[i].equiv;
1163 if(!second->usesEquiv) {
1164 /* The first link is the terminal node */
1165 continue;
1166 }
1167 first = second->equiv;
1168 while(first->usesEquiv) {
1169 if(first == second) {
1170 errStr = PR_smprintf(errString[EQUIV_LOOP],
1171 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1172 goto loser;
1173 }
1174 first = first->equiv;
1175 if(!first->usesEquiv) {
1176 break;
1177 }
1178 if(first == second) {
1179 errStr = PR_smprintf(errString[EQUIV_LOOP],
1180 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1181 goto loser;
1182 }
1183 second = second->equiv;
1184 first = first->equiv;
1185 }
1186 _this->platforms[i].equiv = first;
1187 }
1188 }
1190 loser:
1191 if(iter) {
1192 Pk11Install_ListIter_delete(iter);
1193 PR_Free(iter);
1194 iter = NULL;
1195 }
1196 if(subiter) {
1197 Pk11Install_ListIter_delete(subiter);
1198 PR_Free(subiter);
1199 subiter = NULL;
1200 }
1201 return errStr;
1202 }
1204 /*
1205 //////////////////////////////////////////////////////////////////////////
1206 // Method: GetBestPlatform
1207 // Class: Pk11Install_Info
1208 // Takes: char *myPlatform, the platform we are currently running
1209 // on.
1210 */
1211 Pk11Install_Platform*
1212 Pk11Install_Info_GetBestPlatform(Pk11Install_Info* _this, char *myPlatform)
1213 {
1214 Pk11Install_PlatformName plat;
1215 char *errStr;
1216 int i, j;
1218 errStr=NULL;
1220 Pk11Install_PlatformName_init(&plat);
1221 if( (errStr=Pk11Install_PlatformName_Generate(&plat, myPlatform)) ) {
1222 PR_smprintf_free(errStr);
1223 return NULL;
1224 }
1226 /* First try real platforms */
1227 for(i=0; i < _this->numPlatforms; i++) {
1228 if(Pk11Install_PlatformName_equal(&_this->platforms[i].name,&plat)) {
1229 if(_this->platforms[i].equiv) {
1230 return _this->platforms[i].equiv;
1231 }
1232 else {
1233 return &_this->platforms[i];
1234 }
1235 }
1236 }
1238 /* Now try forward compatible platforms */
1239 for(i=0; i < _this->numForwardCompatible; i++) {
1240 if(Pk11Install_PlatformName_lteq(&_this->forwardCompatible[i],&plat)) {
1241 break;
1242 }
1243 }
1244 if(i == _this->numForwardCompatible) {
1245 return NULL;
1246 }
1248 /* Got a forward compatible name, find the actual platform. */
1249 for(j=0; j < _this->numPlatforms; j++) {
1250 if(Pk11Install_PlatformName_equal(&_this->platforms[j].name,
1251 &_this->forwardCompatible[i])) {
1252 if(_this->platforms[j].equiv) {
1253 return _this->platforms[j].equiv;
1254 } else {
1255 return &_this->platforms[j];
1256 }
1257 }
1258 }
1260 return NULL;
1261 }
1263 /*
1264 //////////////////////////////////////////////////////////////////////////
1265 // Method: Print
1266 // Class: Pk11Install_Info
1267 */
1268 void
1269 Pk11Install_Info_Print(Pk11Install_Info* _this, int pad)
1270 {
1271 int i;
1273 PAD(pad); printf("Forward Compatible:\n");
1274 for(i = 0; i < _this->numForwardCompatible; i++) {
1275 Pk11Install_PlatformName_Print(&_this->forwardCompatible[i],pad+PADINC);
1276 PAD(pad); printf("-------------------\n");
1277 }
1278 PAD(pad); printf("Platforms:\n");
1279 for( i = 0; i < _this->numPlatforms; i++) {
1280 Pk11Install_Platform_Print(&_this->platforms[i],pad+PADINC);
1281 PAD(pad); printf("-------------------\n");
1282 }
1283 }
1285 /*
1286 //////////////////////////////////////////////////////////////////////////
1287 */
1288 static char*
1289 PR_Strdup(const char* str)
1290 {
1291 char *tmp;
1292 tmp = (char*) PR_Malloc((unsigned int)(strlen(str)+1));
1293 strcpy(tmp, str);
1294 return tmp;
1295 }
1297 /* The global value list, the top of the tree */
1298 Pk11Install_ValueList* Pk11Install_valueList=NULL;
1300 /****************************************************************************/
1301 void
1302 Pk11Install_ValueList_AddItem(Pk11Install_ValueList* _this,
1303 Pk11Install_Value *item)
1304 {
1305 _this->numItems++;
1306 if (item->type == STRING_VALUE) {
1307 _this->numStrings++;
1308 } else {
1309 _this->numPairs++;
1310 }
1311 item->next = _this->head;
1312 _this->head = item;
1313 }
1315 /****************************************************************************/
1316 Pk11Install_ListIter*
1317 Pk11Install_ListIter_new_default()
1318 {
1319 Pk11Install_ListIter* new_this;
1320 new_this = (Pk11Install_ListIter*)
1321 PR_Malloc(sizeof(Pk11Install_ListIter));
1322 Pk11Install_ListIter_init(new_this);
1323 return new_this;
1324 }
1326 /****************************************************************************/
1327 void
1328 Pk11Install_ListIter_init(Pk11Install_ListIter* _this)
1329 {
1330 _this->list = NULL;
1331 _this->current = NULL;
1332 }
1334 /****************************************************************************/
1335 Pk11Install_ListIter*
1336 Pk11Install_ListIter_new(const Pk11Install_ValueList *_list)
1337 {
1338 Pk11Install_ListIter* new_this;
1339 new_this = (Pk11Install_ListIter*)
1340 PR_Malloc(sizeof(Pk11Install_ListIter));
1341 new_this->list = _list;
1342 new_this->current = _list->head;
1343 return new_this;
1344 }
1346 /****************************************************************************/
1347 void
1348 Pk11Install_ListIter_delete(Pk11Install_ListIter* _this)
1349 {
1350 _this->list=NULL;
1351 _this->current=NULL;
1352 }
1354 /****************************************************************************/
1355 void
1356 Pk11Install_ListIter_reset(Pk11Install_ListIter* _this)
1357 {
1358 if(_this->list) {
1359 _this->current = _this->list->head;
1360 }
1361 }
1363 /*************************************************************************/
1364 Pk11Install_Value*
1365 Pk11Install_ListIter_nextItem(Pk11Install_ListIter* _this)
1366 {
1367 if(_this->current) {
1368 _this->current = _this->current->next;
1369 }
1371 return _this->current;
1372 }
1374 /****************************************************************************/
1375 Pk11Install_ValueList*
1376 Pk11Install_ValueList_new()
1377 {
1378 Pk11Install_ValueList* new_this;
1379 new_this = (Pk11Install_ValueList*)
1380 PR_Malloc(sizeof(Pk11Install_ValueList));
1381 new_this->numItems = 0;
1382 new_this->numPairs = 0;
1383 new_this->numStrings = 0;
1384 new_this->head = NULL;
1385 return new_this;
1386 }
1388 /****************************************************************************/
1389 void
1390 Pk11Install_ValueList_delete(Pk11Install_ValueList* _this)
1391 {
1393 Pk11Install_Value *tmp;
1394 Pk11Install_Value *list;
1395 list = _this->head;
1397 while(list != NULL) {
1398 tmp = list;
1399 list = list->next;
1400 PR_Free(tmp);
1401 }
1402 PR_Free(_this);
1403 }
1405 /****************************************************************************/
1406 Pk11Install_Value*
1407 Pk11Install_Value_new_default()
1408 {
1409 Pk11Install_Value* new_this;
1410 new_this = (Pk11Install_Value*)PR_Malloc(sizeof(Pk11Install_Value));
1411 new_this->type = STRING_VALUE;
1412 new_this->string = NULL;
1413 new_this->pair = NULL;
1414 new_this->next = NULL;
1415 return new_this;
1416 }
1418 /****************************************************************************/
1419 Pk11Install_Value*
1420 Pk11Install_Value_new(ValueType _type, Pk11Install_Pointer ptr)
1421 {
1422 Pk11Install_Value* new_this;
1423 new_this = Pk11Install_Value_new_default();
1424 new_this->type = _type;
1425 if(_type == STRING_VALUE) {
1426 new_this->pair = NULL;
1427 new_this->string = ptr.string;
1428 } else {
1429 new_this->string = NULL;
1430 new_this->pair = ptr.pair;
1431 }
1432 return new_this;
1433 }
1435 /****************************************************************************/
1436 void
1437 Pk11Install_Value_delete(Pk11Install_Value* _this)
1438 {
1439 if(_this->type == STRING_VALUE) {
1440 PR_Free(_this->string);
1441 } else {
1442 PR_Free(_this->pair);
1443 }
1444 }
1446 /****************************************************************************/
1447 Pk11Install_Pair*
1448 Pk11Install_Pair_new_default()
1449 {
1450 return Pk11Install_Pair_new(NULL,NULL);
1451 }
1453 /****************************************************************************/
1454 Pk11Install_Pair*
1455 Pk11Install_Pair_new(char *_key, Pk11Install_ValueList *_list)
1456 {
1457 Pk11Install_Pair* new_this;
1458 new_this = (Pk11Install_Pair*)PR_Malloc(sizeof(Pk11Install_Pair));
1459 new_this->key = _key;
1460 new_this->list = _list;
1461 return new_this;
1462 }
1464 /****************************************************************************/
1465 void
1466 Pk11Install_Pair_delete(Pk11Install_Pair* _this)
1467 {
1468 PR_Free(_this->key);
1469 Pk11Install_ValueList_delete(_this->list);
1470 PR_Free(_this->list);
1471 }
1473 /*************************************************************************/
1474 void
1475 Pk11Install_Pair_Print(Pk11Install_Pair* _this, int pad)
1476 {
1477 while (_this) {
1478 /*PAD(pad); printf("**Pair\n");
1479 PAD(pad); printf("***Key====\n");*/
1480 PAD(pad); printf("%s {\n", _this->key);
1481 /*PAD(pad); printf("====\n");*/
1482 /*PAD(pad); printf("***ValueList\n");*/
1483 Pk11Install_ValueList_Print(_this->list,pad+PADINC);
1484 PAD(pad); printf("}\n");
1485 }
1486 }
1488 /*************************************************************************/
1489 void
1490 Pk11Install_ValueList_Print(Pk11Install_ValueList* _this, int pad)
1491 {
1492 Pk11Install_Value *v;
1494 /*PAD(pad);printf("**Value List**\n");*/
1495 for(v = _this->head; v != NULL; v=v->next) {
1496 Pk11Install_Value_Print(v,pad);
1497 }
1498 }
1500 /*************************************************************************/
1501 void
1502 Pk11Install_Value_Print(Pk11Install_Value* _this, int pad)
1503 {
1504 /*PAD(pad); printf("**Value, type=%s\n",
1505 type==STRING_VALUE ? "string" : "pair");*/
1506 if(_this->type==STRING_VALUE) {
1507 /*PAD(pad+PADINC); printf("====\n");*/
1508 PAD(pad); printf("%s\n", _this->string);
1509 /*PAD(pad+PADINC); printf("====\n");*/
1510 } else {
1511 Pk11Install_Pair_Print(_this->pair,pad+PADINC);
1512 }
1513 }