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