install-ds.c (47681B)
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 pad_i; \ 94 for (pad_i = 0; pad_i < (x); pad_i++) \ 95 printf(" "); \ 96 } 97 #define PADINC 4 98 99 Pk11Install_File* 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 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 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 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* 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 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* 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 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 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 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* 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 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 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 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* 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* 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 snprintf(buf, sizeof(buf), "%s.", _this->verString[i]); 624 strcat(tmp, buf); 625 } 626 if (i < _this->numDigits) { 627 snprintf(buf, sizeof(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 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* 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 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 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 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* 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 PR_smprintf_free(errStr); 895 errStr = tmp; 896 goto loser; 897 } 898 _this->usesEquiv = PR_TRUE; 899 } 900 } 901 } 902 903 /* Make sure we either have an EquivalentPlatform or all the other info */ 904 if (_this->usesEquiv && 905 (gotFiles || gotModuleFile || gotModuleName || gotMech || gotCipher)) { 906 errStr = PR_smprintf(errString[EQUIV_TOO_MUCH_INFO], 907 Pk11Install_PlatformName_GetString(&_this->name)); 908 goto loser; 909 } 910 if (!gotFiles && !_this->usesEquiv) { 911 errStr = PR_smprintf(errString[NO_FILES], 912 Pk11Install_PlatformName_GetString(&_this->name)); 913 goto loser; 914 } 915 if (!gotModuleFile && !_this->usesEquiv) { 916 errStr = PR_smprintf(errString[NO_MODULE_FILE], 917 Pk11Install_PlatformName_GetString(&_this->name)); 918 goto loser; 919 } 920 if (!gotModuleName && !_this->usesEquiv) { 921 errStr = PR_smprintf(errString[NO_MODULE_NAME], 922 Pk11Install_PlatformName_GetString(&_this->name)); 923 goto loser; 924 } 925 926 /* Point the modFile pointer to the correct file */ 927 if (gotModuleFile) { 928 for (i = 0; i < _this->numFiles; i++) { 929 if (!PORT_Strcasecmp(_this->moduleFile, _this->files[i].jarPath)) { 930 _this->modFile = i; 931 break; 932 } 933 } 934 if (_this->modFile == -1) { 935 errStr = PR_smprintf(errString[UNKNOWN_MODULE_FILE], 936 _this->moduleFile, 937 Pk11Install_PlatformName_GetString(&_this->name)); 938 goto loser; 939 } 940 } 941 942 loser: 943 if (iter) { 944 PR_Free(iter); 945 } 946 if (subiter) { 947 PR_Free(subiter); 948 } 949 return errStr; 950 } 951 952 /* 953 ////////////////////////////////////////////////////////////////////////// 954 // Method: Print 955 // Class: Pk11Install_Platform 956 */ 957 void 958 Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad) 959 { 960 int i; 961 962 PAD(pad); 963 printf("Name:\n"); 964 Pk11Install_PlatformName_Print(&_this->name, pad + PADINC); 965 PAD(pad); 966 printf("equivName:\n"); 967 Pk11Install_PlatformName_Print(&_this->equivName, pad + PADINC); 968 PAD(pad); 969 if (_this->usesEquiv) { 970 printf("Uses equiv, which points to:\n"); 971 Pk11Install_Platform_Print(_this->equiv, pad + PADINC); 972 } else { 973 printf("Doesn't use equiv\n"); 974 } 975 PAD(pad); 976 printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile : "<NULL>"); 977 PAD(pad); 978 printf("mechFlags: %lx\n", _this->mechFlags); 979 PAD(pad); 980 printf("cipherFlags: %lx\n", _this->cipherFlags); 981 PAD(pad); 982 printf("Files:\n"); 983 for (i = 0; i < _this->numFiles; i++) { 984 Pk11Install_File_Print(&_this->files[i], pad + PADINC); 985 PAD(pad); 986 printf("--------------------\n"); 987 } 988 } 989 990 /* 991 ////////////////////////////////////////////////////////////////////////// 992 // Method: Pk11Install_Info 993 // Class: Pk11Install_Info 994 */ 995 Pk11Install_Info* 996 Pk11Install_Info_new() 997 { 998 Pk11Install_Info* new_this; 999 new_this = (Pk11Install_Info*)PR_Malloc(sizeof(Pk11Install_Info)); 1000 Pk11Install_Info_init(new_this); 1001 return new_this; 1002 } 1003 1004 void 1005 Pk11Install_Info_init(Pk11Install_Info* _this) 1006 { 1007 _this->platforms = NULL; 1008 _this->numPlatforms = 0; 1009 _this->forwardCompatible = NULL; 1010 _this->numForwardCompatible = 0; 1011 } 1012 1013 /* 1014 ////////////////////////////////////////////////////////////////////////// 1015 // Method: ~Pk11Install_Info 1016 // Class: Pk11Install_Info 1017 */ 1018 void 1019 Pk11Install_Info_delete(Pk11Install_Info* _this) 1020 { 1021 Pk11Install_Info_Cleanup(_this); 1022 } 1023 1024 /* 1025 ////////////////////////////////////////////////////////////////////////// 1026 // Method: Cleanup 1027 // Class: Pk11Install_Info 1028 */ 1029 void 1030 Pk11Install_Info_Cleanup(Pk11Install_Info* _this) 1031 { 1032 int i; 1033 if (_this->platforms) { 1034 for (i = 0; i < _this->numPlatforms; i++) { 1035 Pk11Install_Platform_delete(&_this->platforms[i]); 1036 } 1037 PR_Free(_this->platforms); 1038 _this->platforms = NULL; 1039 _this->numPlatforms = 0; 1040 } 1041 1042 if (_this->forwardCompatible) { 1043 for (i = 0; i < _this->numForwardCompatible; i++) { 1044 Pk11Install_PlatformName_delete(&_this->forwardCompatible[i]); 1045 } 1046 PR_Free(_this->forwardCompatible); 1047 _this->numForwardCompatible = 0; 1048 } 1049 } 1050 1051 /* 1052 ////////////////////////////////////////////////////////////////////////// 1053 // Method: Generate 1054 // Class: Pk11Install_Info 1055 // Takes: Pk11Install_ValueList *list, the top-level list 1056 // resulting from parsing an installer file. 1057 // Returns: char*, NULL if successful, otherwise an error string. 1058 // Caller is responsible for freeing memory. 1059 */ 1060 char* 1061 Pk11Install_Info_Generate(Pk11Install_Info* _this, 1062 const Pk11Install_ValueList* list) 1063 { 1064 char* errStr; 1065 Pk11Install_ListIter* iter; 1066 Pk11Install_Value* val; 1067 Pk11Install_Pair* pair; 1068 Pk11Install_ListIter* subiter; 1069 Pk11Install_Value* subval; 1070 Pk11Install_Platform *first, *second; 1071 int i, j; 1072 1073 errStr = NULL; 1074 iter = subiter = NULL; 1075 Pk11Install_Info_Cleanup(_this); 1076 1077 iter = Pk11Install_ListIter_new(list); 1078 for (; (val = iter->current); Pk11Install_ListIter_nextItem(iter)) { 1079 if (val->type == PAIR_VALUE) { 1080 pair = val->pair; 1081 1082 if (!PORT_Strcasecmp(pair->key, FORWARD_COMPATIBLE_STRING)) { 1083 subiter = Pk11Install_ListIter_new(pair->list); 1084 _this->numForwardCompatible = pair->list->numStrings; 1085 _this->forwardCompatible = (Pk11Install_PlatformName*) 1086 PR_Malloc(sizeof(Pk11Install_PlatformName) * 1087 _this->numForwardCompatible); 1088 for (i = 0; i < _this->numForwardCompatible; i++, 1089 Pk11Install_ListIter_nextItem(subiter)) { 1090 subval = subiter->current; 1091 if (subval->type == STRING_VALUE) { 1092 errStr = Pk11Install_PlatformName_Generate( 1093 &_this->forwardCompatible[i], subval->string); 1094 if (errStr) { 1095 goto loser; 1096 } 1097 } 1098 } 1099 Pk11Install_ListIter_delete(&subiter); 1100 } else if (!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) { 1101 subiter = Pk11Install_ListIter_new(pair->list); 1102 _this->numPlatforms = pair->list->numPairs; 1103 _this->platforms = (Pk11Install_Platform*) 1104 PR_Malloc(sizeof(Pk11Install_Platform) * 1105 _this->numPlatforms); 1106 for (i = 0; i < _this->numPlatforms; i++, 1107 Pk11Install_ListIter_nextItem(subiter)) { 1108 Pk11Install_Platform_init(&_this->platforms[i]); 1109 subval = subiter->current; 1110 if (subval->type == PAIR_VALUE) { 1111 errStr = Pk11Install_Platform_Generate(&_this->platforms[i], subval->pair); 1112 if (errStr) { 1113 goto loser; 1114 } 1115 } 1116 } 1117 Pk11Install_ListIter_delete(&subiter); 1118 } 1119 } 1120 } 1121 1122 if (_this->numPlatforms == 0) { 1123 errStr = PR_smprintf(errString[NO_PLATFORMS]); 1124 goto loser; 1125 } 1126 1127 /* 1128 // 1129 // Now process equivalent platforms 1130 // 1131 1132 // First the naive pass 1133 */ 1134 for (i = 0; i < _this->numPlatforms; i++) { 1135 if (_this->platforms[i].usesEquiv) { 1136 _this->platforms[i].equiv = NULL; 1137 for (j = 0; j < _this->numPlatforms; j++) { 1138 if (Pk11Install_PlatformName_equal(&_this->platforms[i].equivName, 1139 &_this->platforms[j].name)) { 1140 if (i == j) { 1141 errStr = PR_smprintf(errString[EQUIV_LOOP], 1142 Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1143 goto loser; 1144 } 1145 _this->platforms[i].equiv = &_this->platforms[j]; 1146 break; 1147 } 1148 } 1149 if (_this->platforms[i].equiv == NULL) { 1150 errStr = PR_smprintf(errString[BOGUS_EQUIV], 1151 Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1152 goto loser; 1153 } 1154 } 1155 } 1156 1157 /* 1158 // Now the intelligent pass, which will also detect loops. 1159 // We will send two pointers through the linked list of equivalent 1160 // platforms. Both start with the current node. "first" traverses 1161 // two nodes for each iteration. "second" lags behind, only traversing 1162 // one node per iteration. Eventually one of two things will happen: 1163 // first will hit the end of the list (a platform that doesn't use 1164 // an equivalency), or first will equal second if there is a loop. 1165 */ 1166 for (i = 0; i < _this->numPlatforms; i++) { 1167 if (_this->platforms[i].usesEquiv) { 1168 second = _this->platforms[i].equiv; 1169 if (!second->usesEquiv) { 1170 /* The first link is the terminal node */ 1171 continue; 1172 } 1173 first = second->equiv; 1174 while (first->usesEquiv) { 1175 if (first == second) { 1176 errStr = PR_smprintf(errString[EQUIV_LOOP], 1177 Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1178 goto loser; 1179 } 1180 first = first->equiv; 1181 if (!first->usesEquiv) { 1182 break; 1183 } 1184 if (first == second) { 1185 errStr = PR_smprintf(errString[EQUIV_LOOP], 1186 Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1187 goto loser; 1188 } 1189 second = second->equiv; 1190 first = first->equiv; 1191 } 1192 _this->platforms[i].equiv = first; 1193 } 1194 } 1195 1196 loser: 1197 if (iter) { 1198 Pk11Install_ListIter_delete(&iter); 1199 } 1200 if (subiter) { 1201 Pk11Install_ListIter_delete(&subiter); 1202 } 1203 return errStr; 1204 } 1205 1206 /* 1207 ////////////////////////////////////////////////////////////////////////// 1208 // Method: GetBestPlatform 1209 // Class: Pk11Install_Info 1210 // Takes: char *myPlatform, the platform we are currently running 1211 // on. 1212 */ 1213 Pk11Install_Platform* 1214 Pk11Install_Info_GetBestPlatform(Pk11Install_Info* _this, char* myPlatform) 1215 { 1216 Pk11Install_PlatformName plat; 1217 char* errStr; 1218 int i, j; 1219 1220 errStr = NULL; 1221 1222 Pk11Install_PlatformName_init(&plat); 1223 if ((errStr = Pk11Install_PlatformName_Generate(&plat, myPlatform))) { 1224 PR_smprintf_free(errStr); 1225 return NULL; 1226 } 1227 1228 /* First try real platforms */ 1229 for (i = 0; i < _this->numPlatforms; i++) { 1230 if (Pk11Install_PlatformName_equal(&_this->platforms[i].name, &plat)) { 1231 if (_this->platforms[i].equiv) { 1232 return _this->platforms[i].equiv; 1233 } else { 1234 return &_this->platforms[i]; 1235 } 1236 } 1237 } 1238 1239 /* Now try forward compatible platforms */ 1240 for (i = 0; i < _this->numForwardCompatible; i++) { 1241 if (Pk11Install_PlatformName_lteq(&_this->forwardCompatible[i], &plat)) { 1242 break; 1243 } 1244 } 1245 if (i == _this->numForwardCompatible) { 1246 return NULL; 1247 } 1248 1249 /* Got a forward compatible name, find the actual platform. */ 1250 for (j = 0; j < _this->numPlatforms; j++) { 1251 if (Pk11Install_PlatformName_equal(&_this->platforms[j].name, 1252 &_this->forwardCompatible[i])) { 1253 if (_this->platforms[j].equiv) { 1254 return _this->platforms[j].equiv; 1255 } else { 1256 return &_this->platforms[j]; 1257 } 1258 } 1259 } 1260 1261 return NULL; 1262 } 1263 1264 /* 1265 ////////////////////////////////////////////////////////////////////////// 1266 // Method: Print 1267 // Class: Pk11Install_Info 1268 */ 1269 void 1270 Pk11Install_Info_Print(Pk11Install_Info* _this, int pad) 1271 { 1272 int i; 1273 1274 PAD(pad); 1275 printf("Forward Compatible:\n"); 1276 for (i = 0; i < _this->numForwardCompatible; i++) { 1277 Pk11Install_PlatformName_Print(&_this->forwardCompatible[i], pad + PADINC); 1278 PAD(pad); 1279 printf("-------------------\n"); 1280 } 1281 PAD(pad); 1282 printf("Platforms:\n"); 1283 for (i = 0; i < _this->numPlatforms; i++) { 1284 Pk11Install_Platform_Print(&_this->platforms[i], pad + PADINC); 1285 PAD(pad); 1286 printf("-------------------\n"); 1287 } 1288 } 1289 1290 /* 1291 ////////////////////////////////////////////////////////////////////////// 1292 */ 1293 static char* 1294 PR_Strdup(const char* str) 1295 { 1296 char* tmp; 1297 tmp = (char*)PR_Malloc((unsigned int)(strlen(str) + 1)); 1298 strcpy(tmp, str); 1299 return tmp; 1300 } 1301 1302 /* The global value list, the top of the tree */ 1303 Pk11Install_ValueList* Pk11Install_valueList = NULL; 1304 1305 /****************************************************************************/ 1306 void 1307 Pk11Install_ValueList_AddItem(Pk11Install_ValueList* _this, 1308 Pk11Install_Value* item) 1309 { 1310 _this->numItems++; 1311 if (item->type == STRING_VALUE) { 1312 _this->numStrings++; 1313 } else { 1314 _this->numPairs++; 1315 } 1316 item->next = _this->head; 1317 _this->head = item; 1318 } 1319 1320 /****************************************************************************/ 1321 Pk11Install_ListIter* 1322 Pk11Install_ListIter_new_default() 1323 { 1324 Pk11Install_ListIter* new_this; 1325 new_this = (Pk11Install_ListIter*) 1326 PR_Malloc(sizeof(Pk11Install_ListIter)); 1327 Pk11Install_ListIter_init(new_this); 1328 return new_this; 1329 } 1330 1331 /****************************************************************************/ 1332 void 1333 Pk11Install_ListIter_init(Pk11Install_ListIter* _this) 1334 { 1335 _this->list = NULL; 1336 _this->current = NULL; 1337 } 1338 1339 /****************************************************************************/ 1340 Pk11Install_ListIter* 1341 Pk11Install_ListIter_new(const Pk11Install_ValueList* _list) 1342 { 1343 Pk11Install_ListIter* new_this; 1344 new_this = (Pk11Install_ListIter*) 1345 PR_Malloc(sizeof(Pk11Install_ListIter)); 1346 new_this->list = _list; 1347 new_this->current = _list->head; 1348 return new_this; 1349 } 1350 1351 /****************************************************************************/ 1352 void 1353 Pk11Install_ListIter_delete(Pk11Install_ListIter** _this) 1354 { 1355 (*_this)->list = NULL; 1356 (*_this)->current = NULL; 1357 PR_Free(*_this); 1358 *_this = NULL; 1359 } 1360 1361 /****************************************************************************/ 1362 void 1363 Pk11Install_ListIter_reset(Pk11Install_ListIter* _this) 1364 { 1365 if (_this->list) { 1366 _this->current = _this->list->head; 1367 } 1368 } 1369 1370 /*************************************************************************/ 1371 Pk11Install_Value* 1372 Pk11Install_ListIter_nextItem(Pk11Install_ListIter* _this) 1373 { 1374 if (_this->current) { 1375 _this->current = _this->current->next; 1376 } 1377 1378 return _this->current; 1379 } 1380 1381 /****************************************************************************/ 1382 Pk11Install_ValueList* 1383 Pk11Install_ValueList_new() 1384 { 1385 Pk11Install_ValueList* new_this; 1386 new_this = (Pk11Install_ValueList*) 1387 PR_Malloc(sizeof(Pk11Install_ValueList)); 1388 new_this->numItems = 0; 1389 new_this->numPairs = 0; 1390 new_this->numStrings = 0; 1391 new_this->head = NULL; 1392 return new_this; 1393 } 1394 1395 /****************************************************************************/ 1396 void 1397 Pk11Install_ValueList_delete(Pk11Install_ValueList* _this) 1398 { 1399 1400 Pk11Install_Value* tmp; 1401 Pk11Install_Value* list; 1402 list = _this->head; 1403 1404 while (list != NULL) { 1405 tmp = list; 1406 list = list->next; 1407 PR_Free(tmp); 1408 } 1409 PR_Free(_this); 1410 } 1411 1412 /****************************************************************************/ 1413 Pk11Install_Value* 1414 Pk11Install_Value_new_default() 1415 { 1416 Pk11Install_Value* new_this; 1417 new_this = (Pk11Install_Value*)PR_Malloc(sizeof(Pk11Install_Value)); 1418 new_this->type = STRING_VALUE; 1419 new_this->string = NULL; 1420 new_this->pair = NULL; 1421 new_this->next = NULL; 1422 return new_this; 1423 } 1424 1425 /****************************************************************************/ 1426 Pk11Install_Value* 1427 Pk11Install_Value_new(ValueType _type, Pk11Install_Pointer ptr) 1428 { 1429 Pk11Install_Value* new_this; 1430 new_this = Pk11Install_Value_new_default(); 1431 new_this->type = _type; 1432 if (_type == STRING_VALUE) { 1433 new_this->pair = NULL; 1434 new_this->string = ptr.string; 1435 } else { 1436 new_this->string = NULL; 1437 new_this->pair = ptr.pair; 1438 } 1439 return new_this; 1440 } 1441 1442 /****************************************************************************/ 1443 void 1444 Pk11Install_Value_delete(Pk11Install_Value* _this) 1445 { 1446 if (_this->type == STRING_VALUE) { 1447 PR_Free(_this->string); 1448 } else { 1449 PR_Free(_this->pair); 1450 } 1451 } 1452 1453 /****************************************************************************/ 1454 Pk11Install_Pair* 1455 Pk11Install_Pair_new_default() 1456 { 1457 return Pk11Install_Pair_new(NULL, NULL); 1458 } 1459 1460 /****************************************************************************/ 1461 Pk11Install_Pair* 1462 Pk11Install_Pair_new(char* _key, Pk11Install_ValueList* _list) 1463 { 1464 Pk11Install_Pair* new_this; 1465 new_this = (Pk11Install_Pair*)PR_Malloc(sizeof(Pk11Install_Pair)); 1466 new_this->key = _key; 1467 new_this->list = _list; 1468 return new_this; 1469 } 1470 1471 /****************************************************************************/ 1472 void 1473 Pk11Install_Pair_delete(Pk11Install_Pair* _this) 1474 { 1475 PR_Free(_this->key); 1476 Pk11Install_ValueList_delete(_this->list); 1477 } 1478 1479 /*************************************************************************/ 1480 void 1481 Pk11Install_Pair_Print(Pk11Install_Pair* _this, int pad) 1482 { 1483 while (_this) { 1484 /*PAD(pad); printf("**Pair\n"); 1485 PAD(pad); printf("***Key====\n");*/ 1486 PAD(pad); 1487 printf("%s {\n", _this->key); 1488 /*PAD(pad); printf("====\n");*/ 1489 /*PAD(pad); printf("***ValueList\n");*/ 1490 Pk11Install_ValueList_Print(_this->list, pad + PADINC); 1491 PAD(pad); 1492 printf("}\n"); 1493 } 1494 } 1495 1496 /*************************************************************************/ 1497 void 1498 Pk11Install_ValueList_Print(Pk11Install_ValueList* _this, int pad) 1499 { 1500 Pk11Install_Value* v; 1501 1502 /*PAD(pad);printf("**Value List**\n");*/ 1503 for (v = _this->head; v != NULL; v = v->next) { 1504 Pk11Install_Value_Print(v, pad); 1505 } 1506 } 1507 1508 /*************************************************************************/ 1509 void 1510 Pk11Install_Value_Print(Pk11Install_Value* _this, int pad) 1511 { 1512 /*PAD(pad); printf("**Value, type=%s\n", 1513 type==STRING_VALUE ? "string" : "pair");*/ 1514 if (_this->type == STRING_VALUE) { 1515 /*PAD(pad+PADINC); printf("====\n");*/ 1516 PAD(pad); 1517 printf("%s\n", _this->string); 1518 /*PAD(pad+PADINC); printf("====\n");*/ 1519 } else { 1520 Pk11Install_Pair_Print(_this->pair, pad + PADINC); 1521 } 1522 }