1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/modutil/install-ds.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1513 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "install-ds.h" 1.9 +#include <prmem.h> 1.10 +#include <plstr.h> 1.11 +#include <prprf.h> 1.12 +#include <string.h> 1.13 + 1.14 +#define PORT_Strcasecmp PL_strcasecmp 1.15 + 1.16 +#define MODULE_FILE_STRING "ModuleFile" 1.17 +#define MODULE_NAME_STRING "ModuleName" 1.18 +#define MECH_FLAGS_STRING "DefaultMechanismFlags" 1.19 +#define CIPHER_FLAGS_STRING "DefaultCipherFlags" 1.20 +#define FILES_STRING "Files" 1.21 +#define FORWARD_COMPATIBLE_STRING "ForwardCompatible" 1.22 +#define PLATFORMS_STRING "Platforms" 1.23 +#define RELATIVE_DIR_STRING "RelativePath" 1.24 +#define ABSOLUTE_DIR_STRING "AbsolutePath" 1.25 +#define FILE_PERMISSIONS_STRING "FilePermissions" 1.26 +#define EQUIVALENT_PLATFORM_STRING "EquivalentPlatform" 1.27 +#define EXECUTABLE_STRING "Executable" 1.28 + 1.29 +#define DEFAULT_PERMISSIONS 0777 1.30 + 1.31 +#define PLATFORM_SEPARATOR_CHAR ':' 1.32 + 1.33 +/* Error codes */ 1.34 +enum { 1.35 + BOGUS_RELATIVE_DIR=0, 1.36 + BOGUS_ABSOLUTE_DIR, 1.37 + BOGUS_FILE_PERMISSIONS, 1.38 + NO_RELATIVE_DIR, 1.39 + NO_ABSOLUTE_DIR, 1.40 + EMPTY_PLATFORM_STRING, 1.41 + BOGUS_PLATFORM_STRING, 1.42 + REPEAT_MODULE_FILE, 1.43 + REPEAT_MODULE_NAME, 1.44 + BOGUS_MODULE_FILE, 1.45 + BOGUS_MODULE_NAME, 1.46 + REPEAT_MECH, 1.47 + BOGUS_MECH_FLAGS, 1.48 + REPEAT_CIPHER, 1.49 + BOGUS_CIPHER_FLAGS, 1.50 + REPEAT_FILES, 1.51 + REPEAT_EQUIV, 1.52 + BOGUS_EQUIV, 1.53 + EQUIV_TOO_MUCH_INFO, 1.54 + NO_FILES, 1.55 + NO_MODULE_FILE, 1.56 + NO_MODULE_NAME, 1.57 + NO_PLATFORMS, 1.58 + EQUIV_LOOP, 1.59 + UNKNOWN_MODULE_FILE 1.60 +}; 1.61 + 1.62 +/* Indexed by the above error codes */ 1.63 +static const char *errString[] = { 1.64 + "%s: Invalid relative directory", 1.65 + "%s: Invalid absolute directory", 1.66 + "%s: Invalid file permissions", 1.67 + "%s: No relative directory specified", 1.68 + "%s: No absolute directory specified", 1.69 + "Empty string given for platform name", 1.70 + "%s: invalid platform string", 1.71 + "More than one ModuleFile entry given for platform %s", 1.72 + "More than one ModuleName entry given for platform %s", 1.73 + "Invalid ModuleFile specification for platform %s", 1.74 + "Invalid ModuleName specification for platform %s", 1.75 + "More than one DefaultMechanismFlags entry given for platform %s", 1.76 + "Invalid DefaultMechanismFlags specification for platform %s", 1.77 + "More than one DefaultCipherFlags entry given for platform %s", 1.78 + "Invalid DefaultCipherFlags entry given for platform %s", 1.79 + "More than one Files entry given for platform %s", 1.80 + "More than one EquivalentPlatform entry given for platform %s", 1.81 + "Invalid EquivalentPlatform specification for platform %s", 1.82 + "Module %s uses an EquivalentPlatform but also specifies its own" 1.83 + " information", 1.84 + "No Files specification in module %s", 1.85 + "No ModuleFile specification in module %s", 1.86 + "No ModuleName specification in module %s", 1.87 + "No Platforms specification in installer script", 1.88 + "Platform %s has an equivalency loop", 1.89 + "Module file \"%s\" in platform \"%s\" does not exist" 1.90 +}; 1.91 + 1.92 +static char* PR_Strdup(const char* str); 1.93 + 1.94 +#define PAD(x) {int i; for(i=0;i<x;i++) printf(" ");} 1.95 +#define PADINC 4 1.96 + 1.97 +Pk11Install_File* 1.98 +Pk11Install_File_new() 1.99 +{ 1.100 + Pk11Install_File* new_this; 1.101 + new_this = (Pk11Install_File*)PR_Malloc(sizeof(Pk11Install_File)); 1.102 + Pk11Install_File_init(new_this); 1.103 + return new_this; 1.104 +} 1.105 + 1.106 +void 1.107 +Pk11Install_File_init(Pk11Install_File* _this) 1.108 +{ 1.109 + _this->jarPath=NULL; 1.110 + _this->relativePath=NULL; 1.111 + _this->absolutePath=NULL; 1.112 + _this->executable=PR_FALSE; 1.113 + _this->permissions=0; 1.114 +} 1.115 + 1.116 +/* 1.117 +////////////////////////////////////////////////////////////////////////// 1.118 +// Method: ~Pk11Install_File 1.119 +// Class: Pk11Install_File 1.120 +// Notes: Destructor. 1.121 +*/ 1.122 +void 1.123 +Pk11Install_File_delete(Pk11Install_File* _this) 1.124 +{ 1.125 + Pk11Install_File_Cleanup(_this); 1.126 +} 1.127 + 1.128 +/* 1.129 +////////////////////////////////////////////////////////////////////////// 1.130 +// Method: Cleanup 1.131 +// Class: Pk11Install_File 1.132 +*/ 1.133 +void 1.134 +Pk11Install_File_Cleanup(Pk11Install_File* _this) 1.135 +{ 1.136 + if(_this->jarPath) { 1.137 + PR_Free(_this->jarPath); 1.138 + _this->jarPath = NULL; 1.139 + } 1.140 + if(_this->relativePath) { 1.141 + PR_Free(_this->relativePath); 1.142 + _this->relativePath = NULL; 1.143 + } 1.144 + if(_this->absolutePath) { 1.145 + PR_Free(_this->absolutePath); 1.146 + _this->absolutePath = NULL; 1.147 + } 1.148 + 1.149 + _this->permissions = 0; 1.150 + _this->executable = PR_FALSE; 1.151 +} 1.152 + 1.153 +/* 1.154 +////////////////////////////////////////////////////////////////////////// 1.155 +// Method: Generate 1.156 +// Class: Pk11Install_File 1.157 +// Notes: Creates a file data structure from a syntax tree. 1.158 +// Returns: NULL for success, otherwise an error message. 1.159 +*/ 1.160 +char* 1.161 +Pk11Install_File_Generate(Pk11Install_File* _this, 1.162 + const Pk11Install_Pair *pair) 1.163 +{ 1.164 + Pk11Install_ListIter *iter; 1.165 + Pk11Install_Value *val; 1.166 + Pk11Install_Pair *subpair; 1.167 + Pk11Install_ListIter *subiter; 1.168 + Pk11Install_Value *subval; 1.169 + char* errStr; 1.170 + char *endp; 1.171 + PRBool gotPerms; 1.172 + 1.173 + iter=NULL; 1.174 + subiter=NULL; 1.175 + errStr=NULL; 1.176 + gotPerms=PR_FALSE; 1.177 + 1.178 + /* Clear out old values */ 1.179 + Pk11Install_File_Cleanup(_this); 1.180 + 1.181 + _this->jarPath = PR_Strdup(pair->key); 1.182 + 1.183 + /* Go through all the pairs under this file heading */ 1.184 + iter = Pk11Install_ListIter_new(pair->list); 1.185 + for( ; (val = iter->current); Pk11Install_ListIter_nextItem(iter)) { 1.186 + if(val->type == PAIR_VALUE) { 1.187 + subpair = val->pair; 1.188 + 1.189 + /* Relative directory */ 1.190 + if(!PORT_Strcasecmp(subpair->key, RELATIVE_DIR_STRING)) { 1.191 + subiter = Pk11Install_ListIter_new(subpair->list); 1.192 + subval = subiter->current; 1.193 + if(!subval || (subval->type != STRING_VALUE)){ 1.194 + errStr = PR_smprintf(errString[BOGUS_RELATIVE_DIR], 1.195 + _this->jarPath); 1.196 + goto loser; 1.197 + } 1.198 + _this->relativePath = PR_Strdup(subval->string); 1.199 + Pk11Install_ListIter_delete(subiter); 1.200 + subiter = NULL; 1.201 + 1.202 + /* Absolute directory */ 1.203 + } else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) { 1.204 + subiter = Pk11Install_ListIter_new(subpair->list); 1.205 + subval = subiter->current; 1.206 + if(!subval || (subval->type != STRING_VALUE)){ 1.207 + errStr = PR_smprintf(errString[BOGUS_ABSOLUTE_DIR], 1.208 + _this->jarPath); 1.209 + goto loser; 1.210 + } 1.211 + _this->absolutePath = PR_Strdup(subval->string); 1.212 + Pk11Install_ListIter_delete(subiter); 1.213 + subiter = NULL; 1.214 + 1.215 + /* file permissions */ 1.216 + } else if( !PORT_Strcasecmp(subpair->key, 1.217 + FILE_PERMISSIONS_STRING)) { 1.218 + subiter = Pk11Install_ListIter_new(subpair->list); 1.219 + subval = subiter->current; 1.220 + if(!subval || (subval->type != STRING_VALUE) || 1.221 + !subval->string || !subval->string[0]){ 1.222 + errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS], 1.223 + _this->jarPath); 1.224 + goto loser; 1.225 + } 1.226 + _this->permissions = (int) strtol(subval->string, &endp, 8); 1.227 + if(*endp != '\0') { 1.228 + errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS], 1.229 + _this->jarPath); 1.230 + goto loser; 1.231 + } 1.232 + gotPerms = PR_TRUE; 1.233 + Pk11Install_ListIter_delete(subiter); 1.234 + subiter = NULL; 1.235 + } 1.236 + } else { 1.237 + if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) { 1.238 + _this->executable = PR_TRUE; 1.239 + } 1.240 + } 1.241 + } 1.242 + 1.243 + /* Default permission value */ 1.244 + if(!gotPerms) { 1.245 + _this->permissions = DEFAULT_PERMISSIONS; 1.246 + } 1.247 + 1.248 + /* Make sure we got all the information */ 1.249 + if(!_this->relativePath && !_this->absolutePath) { 1.250 + errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath); 1.251 + goto loser; 1.252 + } 1.253 +#if 0 1.254 + if(!_this->relativePath ) { 1.255 + errStr = PR_smprintf(errString[NO_RELATIVE_DIR], _this->jarPath); 1.256 + goto loser; 1.257 + } 1.258 + if(!_this->absolutePath) { 1.259 + errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath); 1.260 + goto loser; 1.261 + } 1.262 +#endif 1.263 + 1.264 +loser: 1.265 + if(iter) { 1.266 + Pk11Install_ListIter_delete(iter); 1.267 + PR_Free(iter); 1.268 + } 1.269 + if(subiter) { 1.270 + Pk11Install_ListIter_delete(subiter); 1.271 + PR_Free(subiter); 1.272 + } 1.273 + return errStr; 1.274 +} 1.275 + 1.276 +/* 1.277 +////////////////////////////////////////////////////////////////////////// 1.278 +// Method: Print 1.279 +// Class: Pk11Install_File 1.280 +*/ 1.281 +void 1.282 +Pk11Install_File_Print(Pk11Install_File* _this, int pad) 1.283 +{ 1.284 + PAD(pad); printf("jarPath: %s\n", 1.285 + _this->jarPath ? _this->jarPath : "<NULL>"); 1.286 + PAD(pad); printf("relativePath: %s\n", 1.287 + _this->relativePath ? _this->relativePath: "<NULL>"); 1.288 + PAD(pad); printf("absolutePath: %s\n", 1.289 + _this->absolutePath ? _this->absolutePath: "<NULL>"); 1.290 + PAD(pad); printf("permissions: %o\n", _this->permissions); 1.291 +} 1.292 + 1.293 +Pk11Install_PlatformName* 1.294 +Pk11Install_PlatformName_new() 1.295 +{ 1.296 + Pk11Install_PlatformName* new_this; 1.297 + new_this = (Pk11Install_PlatformName*) 1.298 + PR_Malloc(sizeof(Pk11Install_PlatformName)); 1.299 + Pk11Install_PlatformName_init(new_this); 1.300 + return new_this; 1.301 +} 1.302 + 1.303 +void 1.304 +Pk11Install_PlatformName_init(Pk11Install_PlatformName* _this) 1.305 +{ 1.306 + _this->OS = NULL; 1.307 + _this->verString = NULL; 1.308 + _this->numDigits = 0; 1.309 + _this->arch = NULL; 1.310 +} 1.311 + 1.312 +/* 1.313 +////////////////////////////////////////////////////////////////////////// 1.314 +// Method: ~Pk11Install_PlatformName 1.315 +// Class: Pk11Install_PlatformName 1.316 +*/ 1.317 +void 1.318 +Pk11Install_PlatformName_delete(Pk11Install_PlatformName* _this) 1.319 +{ 1.320 + Pk11Install_PlatformName_Cleanup(_this); 1.321 +} 1.322 + 1.323 +/* 1.324 +////////////////////////////////////////////////////////////////////////// 1.325 +// Method: Cleanup 1.326 +// Class: Pk11Install_PlatformName 1.327 +*/ 1.328 +void 1.329 +Pk11Install_PlatformName_Cleanup(Pk11Install_PlatformName* _this) 1.330 +{ 1.331 + if(_this->OS) { 1.332 + PR_Free(_this->OS); 1.333 + _this->OS = NULL; 1.334 + } 1.335 + if(_this->verString) { 1.336 + int i; 1.337 + for (i=0; i<_this->numDigits; i++) { 1.338 + PR_Free(_this->verString[i]); 1.339 + } 1.340 + PR_Free(_this->verString); 1.341 + _this->verString = NULL; 1.342 + } 1.343 + if(_this->arch) { 1.344 + PR_Free(_this->arch); 1.345 + _this->arch = NULL; 1.346 + } 1.347 + _this->numDigits = 0; 1.348 +} 1.349 + 1.350 +/* 1.351 +////////////////////////////////////////////////////////////////////////// 1.352 +// Method: Generate 1.353 +// Class: Pk11Install_PlatformName 1.354 +// Notes: Extracts the information from a platform string. 1.355 +*/ 1.356 +char* 1.357 +Pk11Install_PlatformName_Generate(Pk11Install_PlatformName* _this, 1.358 + const char *str) 1.359 +{ 1.360 + char *errStr; 1.361 + char *copy; 1.362 + char *end, *start; /* start and end of a section (OS, version, arch)*/ 1.363 + char *pend, *pstart; /* start and end of one portion of version*/ 1.364 + char *endp; /* used by strtol*/ 1.365 + int periods, i; 1.366 + 1.367 + errStr=NULL; 1.368 + copy=NULL; 1.369 + 1.370 + if(!str) { 1.371 + errStr = PR_smprintf(errString[EMPTY_PLATFORM_STRING]); 1.372 + goto loser; 1.373 + } 1.374 + copy = PR_Strdup(str); 1.375 + 1.376 + /* 1.377 + // Get the OS 1.378 + */ 1.379 + end = strchr(copy, PLATFORM_SEPARATOR_CHAR); 1.380 + if(!end || end==copy) { 1.381 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.382 + goto loser; 1.383 + } 1.384 + *end = '\0'; 1.385 + 1.386 + _this->OS = PR_Strdup(copy); 1.387 + 1.388 + /* 1.389 + // Get the digits of the version of form: x.x.x (arbitrary number of digits) 1.390 + */ 1.391 + 1.392 + start = end+1; 1.393 + end = strchr(start, PLATFORM_SEPARATOR_CHAR); 1.394 + if(!end) { 1.395 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.396 + goto loser; 1.397 + } 1.398 + *end = '\0'; 1.399 + 1.400 + if(end!=start) { 1.401 + /* Find out how many periods*/ 1.402 + periods = 0; 1.403 + pstart = start; 1.404 + while( (pend=strchr(pstart, '.')) ) { 1.405 + periods++; 1.406 + pstart = pend+1; 1.407 + } 1.408 + _this->numDigits= 1+ periods; 1.409 + _this->verString = (char**)PR_Malloc(sizeof(char*)*_this->numDigits); 1.410 + 1.411 + pstart = start; 1.412 + i = 0; 1.413 + /* Get the digits before each period*/ 1.414 + while( (pend=strchr(pstart, '.')) ) { 1.415 + if(pend == pstart) { 1.416 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.417 + goto loser; 1.418 + } 1.419 + *pend = '\0'; 1.420 + _this->verString[i] = PR_Strdup(pstart); 1.421 + endp = pend; 1.422 + if(endp==pstart || (*endp != '\0')) { 1.423 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.424 + goto loser; 1.425 + } 1.426 + pstart = pend+1; 1.427 + i++; 1.428 + } 1.429 + /* Last digit comes after the last period*/ 1.430 + if(*pstart == '\0') { 1.431 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.432 + goto loser; 1.433 + } 1.434 + _this->verString[i] = PR_Strdup(pstart); 1.435 + /* 1.436 + if(endp==pstart || (*endp != '\0')) { 1.437 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.438 + goto loser; 1.439 + } 1.440 + */ 1.441 + } else { 1.442 + _this->verString = NULL; 1.443 + _this->numDigits = 0; 1.444 + } 1.445 + 1.446 + /* 1.447 + // Get the architecture 1.448 + */ 1.449 + start = end+1; 1.450 + if( strchr(start, PLATFORM_SEPARATOR_CHAR) ) { 1.451 + errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str); 1.452 + goto loser; 1.453 + } 1.454 + _this->arch = PR_Strdup(start); 1.455 + 1.456 + if(copy) { 1.457 + PR_Free(copy); 1.458 + } 1.459 + return NULL; 1.460 +loser: 1.461 + if(_this->OS) { 1.462 + PR_Free(_this->OS); 1.463 + _this->OS = NULL; 1.464 + } 1.465 + if(_this->verString) { 1.466 + for (i=0; i<_this->numDigits; i++) { 1.467 + PR_Free(_this->verString[i]); 1.468 + } 1.469 + PR_Free(_this->verString); 1.470 + _this->verString = NULL; 1.471 + } 1.472 + _this->numDigits = 0; 1.473 + if(_this->arch) { 1.474 + PR_Free(_this->arch); 1.475 + _this->arch = NULL; 1.476 + } 1.477 + 1.478 + return errStr; 1.479 +} 1.480 + 1.481 +/* 1.482 +////////////////////////////////////////////////////////////////////////// 1.483 +// Method: operator == 1.484 +// Class: Pk11Install_PlatformName 1.485 +// Returns: PR_TRUE if the platform have the same OS, arch, and version 1.486 +*/ 1.487 +PRBool 1.488 +Pk11Install_PlatformName_equal(Pk11Install_PlatformName* _this, 1.489 + Pk11Install_PlatformName* cmp) 1.490 +{ 1.491 + int i; 1.492 + 1.493 + if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) { 1.494 + return PR_FALSE; 1.495 + } 1.496 + 1.497 + if( PORT_Strcasecmp(_this->OS, cmp->OS) || 1.498 + PORT_Strcasecmp(_this->arch, cmp->arch) || 1.499 + _this->numDigits != cmp->numDigits ) { 1.500 + return PR_FALSE; 1.501 + } 1.502 + 1.503 + for(i=0; i < _this->numDigits; i++) { 1.504 + if(PORT_Strcasecmp(_this->verString[i], cmp->verString[i])) { 1.505 + return PR_FALSE; 1.506 + } 1.507 + } 1.508 + return PR_TRUE; 1.509 +} 1.510 + 1.511 +/* 1.512 +////////////////////////////////////////////////////////////////////////// 1.513 +// Method: operator <= 1.514 +// Class: Pk11Install_PlatformName 1.515 +// Returns: PR_TRUE if the platform have the same OS and arch and a lower 1.516 +// or equal release. 1.517 +*/ 1.518 +PRBool 1.519 +Pk11Install_PlatformName_lteq(Pk11Install_PlatformName* _this, 1.520 + Pk11Install_PlatformName* cmp) 1.521 +{ 1.522 + return (Pk11Install_PlatformName_equal(_this,cmp) || 1.523 + Pk11Install_PlatformName_lt(_this,cmp)) ? PR_TRUE : PR_FALSE; 1.524 +} 1.525 + 1.526 +/* 1.527 +////////////////////////////////////////////////////////////////////////// 1.528 +// Method: operator < 1.529 +// Class: Pk11Install_PlatformName 1.530 +// Returns: PR_TRUE if the platform have the same OS and arch and a greater 1.531 +// release. 1.532 +*/ 1.533 +PRBool 1.534 +Pk11Install_PlatformName_lt(Pk11Install_PlatformName* _this, 1.535 + Pk11Install_PlatformName* cmp) 1.536 +{ 1.537 + int i, scmp; 1.538 + 1.539 + if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) { 1.540 + return PR_FALSE; 1.541 + } 1.542 + 1.543 + if( PORT_Strcasecmp(_this->OS, cmp->OS) ) { 1.544 + return PR_FALSE; 1.545 + } 1.546 + if( PORT_Strcasecmp(_this->arch, cmp->arch) ) { 1.547 + return PR_FALSE; 1.548 + } 1.549 + 1.550 + for(i=0; (i < _this->numDigits) && (i < cmp->numDigits); i++) { 1.551 + scmp = PORT_Strcasecmp(_this->verString[i], cmp->verString[i]); 1.552 + if (scmp > 0) { 1.553 + return PR_FALSE; 1.554 + } else if (scmp < 0) { 1.555 + return PR_TRUE; 1.556 + } 1.557 + } 1.558 + /* All the digits they have in common are the same. */ 1.559 + if(_this->numDigits < cmp->numDigits) { 1.560 + return PR_TRUE; 1.561 + } 1.562 + 1.563 + return PR_FALSE; 1.564 +} 1.565 + 1.566 +/* 1.567 +////////////////////////////////////////////////////////////////////////// 1.568 +// Method: GetString 1.569 +// Class: Pk11Install_PlatformName 1.570 +// Returns: String composed of OS, release, and architecture separated 1.571 +// by the separator char. Memory is allocated by this function 1.572 +// but is the responsibility of the caller to de-allocate. 1.573 +*/ 1.574 +char* 1.575 +Pk11Install_PlatformName_GetString(Pk11Install_PlatformName* _this) 1.576 +{ 1.577 + char *ret; 1.578 + char *ver; 1.579 + char *OS_; 1.580 + char *arch_; 1.581 + 1.582 + OS_=NULL; 1.583 + arch_=NULL; 1.584 + 1.585 + OS_ = _this->OS ? _this->OS : ""; 1.586 + arch_ = _this->arch ? _this->arch : ""; 1.587 + 1.588 + ver = Pk11Install_PlatformName_GetVerString(_this); 1.589 + ret = PR_smprintf("%s%c%s%c%s", OS_, PLATFORM_SEPARATOR_CHAR, ver, 1.590 + PLATFORM_SEPARATOR_CHAR, arch_); 1.591 + 1.592 + PR_Free(ver); 1.593 + 1.594 + return ret; 1.595 +} 1.596 + 1.597 +/* 1.598 +////////////////////////////////////////////////////////////////////////// 1.599 +// Method: GetVerString 1.600 +// Class: Pk11Install_PlatformName 1.601 +// Returns: The version string for this platform, in the form x.x.x with an 1.602 +// arbitrary number of digits. Memory allocated by function, 1.603 +// must be de-allocated by caller. 1.604 +*/ 1.605 +char* 1.606 +Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this) 1.607 +{ 1.608 + char *tmp; 1.609 + char *ret; 1.610 + int i; 1.611 + char buf[80]; 1.612 + 1.613 + tmp = (char*)PR_Malloc(80*_this->numDigits+1); 1.614 + tmp[0] = '\0'; 1.615 + 1.616 + for(i=0; i < _this->numDigits-1; i++) { 1.617 + sprintf(buf, "%s.", _this->verString[i]); 1.618 + strcat(tmp, buf); 1.619 + } 1.620 + if(i < _this->numDigits) { 1.621 + sprintf(buf, "%s", _this->verString[i]); 1.622 + strcat(tmp, buf); 1.623 + } 1.624 + 1.625 + ret = PR_Strdup(tmp); 1.626 + free(tmp); 1.627 + 1.628 + return ret; 1.629 +} 1.630 + 1.631 +/* 1.632 +////////////////////////////////////////////////////////////////////////// 1.633 +// Method: Print 1.634 +// Class: Pk11Install_PlatformName 1.635 +*/ 1.636 +void 1.637 +Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad) 1.638 +{ 1.639 + PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>"); 1.640 + PAD(pad); printf("Digits: "); 1.641 + if(_this->numDigits == 0) { 1.642 + printf("None\n"); 1.643 + } else { 1.644 + printf("%s\n", Pk11Install_PlatformName_GetVerString(_this)); 1.645 + } 1.646 + PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>"); 1.647 +} 1.648 + 1.649 +Pk11Install_Platform* 1.650 +Pk11Install_Platform_new() 1.651 +{ 1.652 + Pk11Install_Platform* new_this; 1.653 + new_this = (Pk11Install_Platform*)PR_Malloc(sizeof(Pk11Install_Platform)); 1.654 + Pk11Install_Platform_init(new_this); 1.655 + return new_this; 1.656 +} 1.657 + 1.658 +void 1.659 +Pk11Install_Platform_init(Pk11Install_Platform* _this) 1.660 +{ 1.661 + Pk11Install_PlatformName_init(&_this->name); 1.662 + Pk11Install_PlatformName_init(&_this->equivName); 1.663 + _this->equiv = NULL; 1.664 + _this->usesEquiv = PR_FALSE; 1.665 + _this->moduleFile = NULL; 1.666 + _this->moduleName = NULL; 1.667 + _this->modFile = -1; 1.668 + _this->mechFlags = 0; 1.669 + _this->cipherFlags = 0; 1.670 + _this->files = NULL; 1.671 + _this->numFiles = 0; 1.672 +} 1.673 + 1.674 +/* 1.675 +////////////////////////////////////////////////////////////////////////// 1.676 +// Method: ~Pk11Install_Platform 1.677 +// Class: Pk11Install_Platform 1.678 +*/ 1.679 +void 1.680 +Pk11Install_Platform_delete(Pk11Install_Platform* _this) 1.681 +{ 1.682 + Pk11Install_Platform_Cleanup(_this); 1.683 +} 1.684 + 1.685 +/* 1.686 +////////////////////////////////////////////////////////////////////////// 1.687 +// Method: Cleanup 1.688 +// Class: Pk11Install_Platform 1.689 +*/ 1.690 +void 1.691 +Pk11Install_Platform_Cleanup(Pk11Install_Platform* _this) 1.692 +{ 1.693 + int i; 1.694 + if(_this->moduleFile) { 1.695 + PR_Free(_this->moduleFile); 1.696 + _this->moduleFile = NULL; 1.697 + } 1.698 + if(_this->moduleName) { 1.699 + PR_Free(_this->moduleName); 1.700 + _this->moduleName = NULL; 1.701 + } 1.702 + if(_this->files) { 1.703 + for (i=0;i<_this->numFiles;i++) { 1.704 + Pk11Install_File_delete(&_this->files[i]); 1.705 + } 1.706 + PR_Free(_this->files); 1.707 + _this->files = NULL; 1.708 + } 1.709 + _this->equiv = NULL; 1.710 + _this->usesEquiv = PR_FALSE; 1.711 + _this->modFile = -1; 1.712 + _this->numFiles = 0; 1.713 + _this->mechFlags = _this->cipherFlags = 0; 1.714 +} 1.715 + 1.716 +/* 1.717 +////////////////////////////////////////////////////////////////////////// 1.718 +// Method: Generate 1.719 +// Class: Pk11Install_Platform 1.720 +// Notes: Creates a platform data structure from a syntax tree. 1.721 +// Returns: NULL for success, otherwise an error message. 1.722 +*/ 1.723 +char* 1.724 +Pk11Install_Platform_Generate(Pk11Install_Platform* _this, 1.725 + const Pk11Install_Pair *pair) 1.726 +{ 1.727 + char* errStr; 1.728 + char* endptr; 1.729 + char* tmp; 1.730 + int i; 1.731 + Pk11Install_ListIter *iter; 1.732 + Pk11Install_Value *val; 1.733 + Pk11Install_Value *subval; 1.734 + Pk11Install_Pair *subpair; 1.735 + Pk11Install_ListIter *subiter; 1.736 + PRBool gotModuleFile, gotModuleName, gotMech, 1.737 + gotCipher, gotFiles, gotEquiv; 1.738 + 1.739 + errStr=NULL; 1.740 + iter=subiter=NULL; 1.741 + val=subval=NULL; 1.742 + subpair=NULL; 1.743 + gotModuleFile=gotModuleName=gotMech=gotCipher=gotFiles=gotEquiv=PR_FALSE; 1.744 + Pk11Install_Platform_Cleanup(_this); 1.745 + 1.746 + errStr = Pk11Install_PlatformName_Generate(&_this->name,pair->key); 1.747 + if(errStr) { 1.748 + tmp = PR_smprintf("%s: %s", pair->key, errStr); 1.749 + PR_smprintf_free(errStr); 1.750 + errStr = tmp; 1.751 + goto loser; 1.752 + } 1.753 + 1.754 + iter = Pk11Install_ListIter_new(pair->list); 1.755 + for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) { 1.756 + if(val->type==PAIR_VALUE) { 1.757 + subpair = val->pair; 1.758 + 1.759 + if( !PORT_Strcasecmp(subpair->key, MODULE_FILE_STRING)) { 1.760 + if(gotModuleFile) { 1.761 + errStr = PR_smprintf(errString[REPEAT_MODULE_FILE], 1.762 + Pk11Install_PlatformName_GetString(&_this->name)); 1.763 + goto loser; 1.764 + } 1.765 + subiter = Pk11Install_ListIter_new(subpair->list); 1.766 + subval = subiter->current; 1.767 + if(!subval || (subval->type != STRING_VALUE)) { 1.768 + errStr = PR_smprintf(errString[BOGUS_MODULE_FILE], 1.769 + Pk11Install_PlatformName_GetString(&_this->name)); 1.770 + goto loser; 1.771 + } 1.772 + _this->moduleFile = PR_Strdup(subval->string); 1.773 + Pk11Install_ListIter_delete(subiter); 1.774 + PR_Free(subiter); 1.775 + subiter = NULL; 1.776 + gotModuleFile = PR_TRUE; 1.777 + } else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){ 1.778 + if(gotModuleName) { 1.779 + errStr = PR_smprintf(errString[REPEAT_MODULE_NAME], 1.780 + Pk11Install_PlatformName_GetString(&_this->name)); 1.781 + goto loser; 1.782 + } 1.783 + subiter = Pk11Install_ListIter_new(subpair->list); 1.784 + subval = subiter->current; 1.785 + if(!subval || (subval->type != STRING_VALUE)) { 1.786 + errStr = PR_smprintf(errString[BOGUS_MODULE_NAME], 1.787 + Pk11Install_PlatformName_GetString(&_this->name)); 1.788 + goto loser; 1.789 + } 1.790 + _this->moduleName = PR_Strdup(subval->string); 1.791 + Pk11Install_ListIter_delete(subiter); 1.792 + PR_Free(subiter); 1.793 + subiter = NULL; 1.794 + gotModuleName = PR_TRUE; 1.795 + } else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) { 1.796 + endptr=NULL; 1.797 + 1.798 + if(gotMech) { 1.799 + errStr = PR_smprintf(errString[REPEAT_MECH], 1.800 + Pk11Install_PlatformName_GetString(&_this->name)); 1.801 + goto loser; 1.802 + } 1.803 + subiter = Pk11Install_ListIter_new(subpair->list); 1.804 + subval = subiter->current; 1.805 + if(!subval || (subval->type != STRING_VALUE)) { 1.806 + errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS], 1.807 + Pk11Install_PlatformName_GetString(&_this->name)); 1.808 + goto loser; 1.809 + } 1.810 + _this->mechFlags = strtol(subval->string, &endptr, 0); 1.811 + if(*endptr!='\0' || (endptr==subval->string) ) { 1.812 + errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS], 1.813 + Pk11Install_PlatformName_GetString(&_this->name)); 1.814 + goto loser; 1.815 + } 1.816 + Pk11Install_ListIter_delete(subiter); 1.817 + PR_Free(subiter); 1.818 + subiter=NULL; 1.819 + gotMech = PR_TRUE; 1.820 + } else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) { 1.821 + endptr=NULL; 1.822 + 1.823 + if(gotCipher) { 1.824 + errStr = PR_smprintf(errString[REPEAT_CIPHER], 1.825 + Pk11Install_PlatformName_GetString(&_this->name)); 1.826 + goto loser; 1.827 + } 1.828 + subiter = Pk11Install_ListIter_new(subpair->list); 1.829 + subval = subiter->current; 1.830 + if(!subval || (subval->type != STRING_VALUE)) { 1.831 + errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS], 1.832 + Pk11Install_PlatformName_GetString(&_this->name)); 1.833 + goto loser; 1.834 + } 1.835 + _this->cipherFlags = strtol(subval->string, &endptr, 0); 1.836 + if(*endptr!='\0' || (endptr==subval->string) ) { 1.837 + errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS], 1.838 + Pk11Install_PlatformName_GetString(&_this->name)); 1.839 + goto loser; 1.840 + } 1.841 + Pk11Install_ListIter_delete(subiter); 1.842 + PR_Free(subiter); 1.843 + subiter=NULL; 1.844 + gotCipher = PR_TRUE; 1.845 + } else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) { 1.846 + if(gotFiles) { 1.847 + errStr = PR_smprintf(errString[REPEAT_FILES], 1.848 + Pk11Install_PlatformName_GetString(&_this->name)); 1.849 + goto loser; 1.850 + } 1.851 + subiter = Pk11Install_ListIter_new(subpair->list); 1.852 + _this->numFiles = subpair->list->numPairs; 1.853 + _this->files = (Pk11Install_File*) 1.854 + PR_Malloc(sizeof(Pk11Install_File)*_this->numFiles); 1.855 + for(i=0; i < _this->numFiles; i++, 1.856 + Pk11Install_ListIter_nextItem(subiter)) { 1.857 + Pk11Install_File_init(&_this->files[i]); 1.858 + val = subiter->current; 1.859 + if(val && (val->type==PAIR_VALUE)) { 1.860 + errStr = Pk11Install_File_Generate(&_this->files[i],val->pair); 1.861 + if(errStr) { 1.862 + tmp = PR_smprintf("%s: %s", 1.863 + Pk11Install_PlatformName_GetString(&_this->name),errStr); 1.864 + PR_smprintf_free(errStr); 1.865 + errStr = tmp; 1.866 + goto loser; 1.867 + } 1.868 + } 1.869 + } 1.870 + gotFiles = PR_TRUE; 1.871 + } else if(!PORT_Strcasecmp(subpair->key, 1.872 + EQUIVALENT_PLATFORM_STRING)) { 1.873 + if(gotEquiv) { 1.874 + errStr = PR_smprintf(errString[REPEAT_EQUIV], 1.875 + Pk11Install_PlatformName_GetString(&_this->name)); 1.876 + goto loser; 1.877 + } 1.878 + subiter = Pk11Install_ListIter_new(subpair->list); 1.879 + subval = subiter->current; 1.880 + if(!subval || (subval->type != STRING_VALUE) ) { 1.881 + errStr = PR_smprintf(errString[BOGUS_EQUIV], 1.882 + Pk11Install_PlatformName_GetString(&_this->name)); 1.883 + goto loser; 1.884 + } 1.885 + errStr = Pk11Install_PlatformName_Generate(&_this->equivName, 1.886 + subval->string); 1.887 + if(errStr) { 1.888 + tmp = PR_smprintf("%s: %s", 1.889 + Pk11Install_PlatformName_GetString(&_this->name), errStr); 1.890 + tmp = PR_smprintf("%s: %s", 1.891 + Pk11Install_PlatformName_GetString(&_this->name), errStr); 1.892 + PR_smprintf_free(errStr); 1.893 + errStr = tmp; 1.894 + goto loser; 1.895 + } 1.896 + _this->usesEquiv = PR_TRUE; 1.897 + } 1.898 + } 1.899 + } 1.900 + 1.901 + /* Make sure we either have an EquivalentPlatform or all the other info */ 1.902 + if(_this->usesEquiv && 1.903 + (gotFiles || gotModuleFile || gotModuleName || gotMech || gotCipher)) { 1.904 + errStr = PR_smprintf(errString[EQUIV_TOO_MUCH_INFO], 1.905 + Pk11Install_PlatformName_GetString(&_this->name)); 1.906 + goto loser; 1.907 + } 1.908 + if(!gotFiles && !_this->usesEquiv) { 1.909 + errStr = PR_smprintf(errString[NO_FILES], 1.910 + Pk11Install_PlatformName_GetString(&_this->name)); 1.911 + goto loser; 1.912 + } 1.913 + if(!gotModuleFile && !_this->usesEquiv) { 1.914 + errStr= PR_smprintf(errString[NO_MODULE_FILE], 1.915 + Pk11Install_PlatformName_GetString(&_this->name)); 1.916 + goto loser; 1.917 + } 1.918 + if(!gotModuleName && !_this->usesEquiv) { 1.919 + errStr = PR_smprintf(errString[NO_MODULE_NAME], 1.920 + Pk11Install_PlatformName_GetString(&_this->name)); 1.921 + goto loser; 1.922 + } 1.923 + 1.924 + /* Point the modFile pointer to the correct file */ 1.925 + if(gotModuleFile) { 1.926 + for(i=0; i < _this->numFiles; i++) { 1.927 + if(!PORT_Strcasecmp(_this->moduleFile, _this->files[i].jarPath) ) { 1.928 + _this->modFile = i; 1.929 + break; 1.930 + } 1.931 + } 1.932 + if(_this->modFile==-1) { 1.933 + errStr = PR_smprintf(errString[UNKNOWN_MODULE_FILE], 1.934 + _this->moduleFile, 1.935 + Pk11Install_PlatformName_GetString(&_this->name)); 1.936 + goto loser; 1.937 + } 1.938 + } 1.939 + 1.940 +loser: 1.941 + if(iter) { 1.942 + PR_Free(iter); 1.943 + } 1.944 + if(subiter) { 1.945 + PR_Free(subiter); 1.946 + } 1.947 + return errStr; 1.948 +} 1.949 + 1.950 +/* 1.951 +////////////////////////////////////////////////////////////////////////// 1.952 +// Method: Print 1.953 +// Class: Pk11Install_Platform 1.954 +*/ 1.955 +void 1.956 +Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad) 1.957 +{ 1.958 + int i; 1.959 + 1.960 + PAD(pad); printf("Name:\n"); 1.961 + Pk11Install_PlatformName_Print(&_this->name,pad+PADINC); 1.962 + PAD(pad); printf("equivName:\n"); 1.963 + Pk11Install_PlatformName_Print(&_this->equivName,pad+PADINC); 1.964 + PAD(pad); 1.965 + if(_this->usesEquiv) { 1.966 + printf("Uses equiv, which points to:\n"); 1.967 + Pk11Install_Platform_Print(_this->equiv,pad+PADINC); 1.968 + } else { 1.969 + printf("Doesn't use equiv\n"); 1.970 + } 1.971 + PAD(pad); 1.972 + printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile 1.973 + : "<NULL>"); 1.974 + PAD(pad); printf("mechFlags: %lx\n", _this->mechFlags); 1.975 + PAD(pad); printf("cipherFlags: %lx\n", _this->cipherFlags); 1.976 + PAD(pad); printf("Files:\n"); 1.977 + for(i=0; i < _this->numFiles; i++) { 1.978 + Pk11Install_File_Print(&_this->files[i],pad+PADINC); 1.979 + PAD(pad); printf("--------------------\n"); 1.980 + } 1.981 +} 1.982 + 1.983 +/* 1.984 +////////////////////////////////////////////////////////////////////////// 1.985 +// Method: Pk11Install_Info 1.986 +// Class: Pk11Install_Info 1.987 +*/ 1.988 +Pk11Install_Info* 1.989 +Pk11Install_Info_new() 1.990 +{ 1.991 + Pk11Install_Info* new_this; 1.992 + new_this = (Pk11Install_Info*)PR_Malloc(sizeof(Pk11Install_Info)); 1.993 + Pk11Install_Info_init(new_this); 1.994 + return new_this; 1.995 +} 1.996 + 1.997 +void 1.998 +Pk11Install_Info_init(Pk11Install_Info* _this) 1.999 +{ 1.1000 + _this->platforms = NULL; 1.1001 + _this->numPlatforms = 0; 1.1002 + _this->forwardCompatible = NULL; 1.1003 + _this->numForwardCompatible = 0; 1.1004 +} 1.1005 + 1.1006 +/* 1.1007 +////////////////////////////////////////////////////////////////////////// 1.1008 +// Method: ~Pk11Install_Info 1.1009 +// Class: Pk11Install_Info 1.1010 +*/ 1.1011 +void 1.1012 +Pk11Install_Info_delete(Pk11Install_Info* _this) 1.1013 +{ 1.1014 + Pk11Install_Info_Cleanup(_this); 1.1015 +} 1.1016 + 1.1017 +/* 1.1018 +////////////////////////////////////////////////////////////////////////// 1.1019 +// Method: Cleanup 1.1020 +// Class: Pk11Install_Info 1.1021 +*/ 1.1022 +void 1.1023 +Pk11Install_Info_Cleanup(Pk11Install_Info* _this) 1.1024 +{ 1.1025 + int i; 1.1026 + if(_this->platforms) { 1.1027 + for (i=0;i<_this->numPlatforms;i++) { 1.1028 + Pk11Install_Platform_delete(&_this->platforms[i]); 1.1029 + } 1.1030 + PR_Free(&_this->platforms); 1.1031 + _this->platforms = NULL; 1.1032 + _this->numPlatforms = 0; 1.1033 + } 1.1034 + 1.1035 + if(_this->forwardCompatible) { 1.1036 + for (i=0;i<_this->numForwardCompatible;i++) { 1.1037 + Pk11Install_PlatformName_delete(&_this->forwardCompatible[i]); 1.1038 + } 1.1039 + PR_Free(&_this->forwardCompatible); 1.1040 + _this->numForwardCompatible = 0; 1.1041 + } 1.1042 +} 1.1043 + 1.1044 +/* 1.1045 +////////////////////////////////////////////////////////////////////////// 1.1046 +// Method: Generate 1.1047 +// Class: Pk11Install_Info 1.1048 +// Takes: Pk11Install_ValueList *list, the top-level list 1.1049 +// resulting from parsing an installer file. 1.1050 +// Returns: char*, NULL if successful, otherwise an error string. 1.1051 +// Caller is responsible for freeing memory. 1.1052 +*/ 1.1053 +char* 1.1054 +Pk11Install_Info_Generate(Pk11Install_Info* _this, 1.1055 + const Pk11Install_ValueList *list) 1.1056 +{ 1.1057 + char *errStr; 1.1058 + Pk11Install_ListIter *iter; 1.1059 + Pk11Install_Value *val; 1.1060 + Pk11Install_Pair *pair; 1.1061 + Pk11Install_ListIter *subiter; 1.1062 + Pk11Install_Value *subval; 1.1063 + Pk11Install_Platform *first, *second; 1.1064 + int i, j; 1.1065 + 1.1066 + errStr=NULL; 1.1067 + iter=subiter=NULL; 1.1068 + Pk11Install_Info_Cleanup(_this); 1.1069 + 1.1070 + iter = Pk11Install_ListIter_new(list); 1.1071 + for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) { 1.1072 + if(val->type == PAIR_VALUE) { 1.1073 + pair = val->pair; 1.1074 + 1.1075 + if(!PORT_Strcasecmp(pair->key, FORWARD_COMPATIBLE_STRING)) { 1.1076 + subiter = Pk11Install_ListIter_new(pair->list); 1.1077 + _this->numForwardCompatible = pair->list->numStrings; 1.1078 + _this->forwardCompatible = (Pk11Install_PlatformName*) 1.1079 + PR_Malloc(sizeof(Pk11Install_PlatformName)* 1.1080 + _this->numForwardCompatible); 1.1081 + for(i=0; i < _this->numForwardCompatible; i++, 1.1082 + Pk11Install_ListIter_nextItem(subiter)) { 1.1083 + subval = subiter->current; 1.1084 + if(subval->type == STRING_VALUE) { 1.1085 + errStr = Pk11Install_PlatformName_Generate( 1.1086 + &_this->forwardCompatible[i], subval->string); 1.1087 + if(errStr) { 1.1088 + goto loser; 1.1089 + } 1.1090 + } 1.1091 + } 1.1092 + Pk11Install_ListIter_delete(subiter); 1.1093 + PR_Free(subiter); 1.1094 + subiter = NULL; 1.1095 + } else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) { 1.1096 + subiter = Pk11Install_ListIter_new(pair->list); 1.1097 + _this->numPlatforms = pair->list->numPairs; 1.1098 + _this->platforms = (Pk11Install_Platform*) 1.1099 + PR_Malloc(sizeof(Pk11Install_Platform)* 1.1100 + _this->numPlatforms); 1.1101 + for(i=0; i < _this->numPlatforms; i++, 1.1102 + Pk11Install_ListIter_nextItem(subiter)) { 1.1103 + Pk11Install_Platform_init(&_this->platforms[i]); 1.1104 + subval = subiter->current; 1.1105 + if(subval->type == PAIR_VALUE) { 1.1106 + errStr = Pk11Install_Platform_Generate(&_this->platforms[i],subval->pair); 1.1107 + if(errStr) { 1.1108 + goto loser; 1.1109 + } 1.1110 + } 1.1111 + } 1.1112 + Pk11Install_ListIter_delete(subiter); 1.1113 + PR_Free(subiter); 1.1114 + subiter = NULL; 1.1115 + } 1.1116 + } 1.1117 + } 1.1118 + 1.1119 + if(_this->numPlatforms == 0) { 1.1120 + errStr = PR_smprintf(errString[NO_PLATFORMS]); 1.1121 + goto loser; 1.1122 + } 1.1123 + 1.1124 +/* 1.1125 + // 1.1126 + // Now process equivalent platforms 1.1127 + // 1.1128 + 1.1129 + // First the naive pass 1.1130 +*/ 1.1131 + for(i=0; i < _this->numPlatforms; i++) { 1.1132 + if(_this->platforms[i].usesEquiv) { 1.1133 + _this->platforms[i].equiv = NULL; 1.1134 + for(j=0; j < _this->numPlatforms; j++) { 1.1135 + if (Pk11Install_PlatformName_equal(&_this->platforms[i].equivName, 1.1136 + &_this->platforms[j].name)) { 1.1137 + if(i==j) { 1.1138 + errStr = PR_smprintf(errString[EQUIV_LOOP], 1.1139 + Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1.1140 + goto loser; 1.1141 + } 1.1142 + _this->platforms[i].equiv = &_this->platforms[j]; 1.1143 + break; 1.1144 + } 1.1145 + } 1.1146 + if(_this->platforms[i].equiv == NULL) { 1.1147 + errStr = PR_smprintf(errString[BOGUS_EQUIV], 1.1148 + Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1.1149 + goto loser; 1.1150 + } 1.1151 + } 1.1152 + } 1.1153 + 1.1154 +/* 1.1155 + // Now the intelligent pass, which will also detect loops. 1.1156 + // We will send two pointers through the linked list of equivalent 1.1157 + // platforms. Both start with the current node. "first" traverses 1.1158 + // two nodes for each iteration. "second" lags behind, only traversing 1.1159 + // one node per iteration. Eventually one of two things will happen: 1.1160 + // first will hit the end of the list (a platform that doesn't use 1.1161 + // an equivalency), or first will equal second if there is a loop. 1.1162 +*/ 1.1163 + for(i=0; i < _this->numPlatforms; i++) { 1.1164 + if(_this->platforms[i].usesEquiv) { 1.1165 + second = _this->platforms[i].equiv; 1.1166 + if(!second->usesEquiv) { 1.1167 + /* The first link is the terminal node */ 1.1168 + continue; 1.1169 + } 1.1170 + first = second->equiv; 1.1171 + while(first->usesEquiv) { 1.1172 + if(first == second) { 1.1173 + errStr = PR_smprintf(errString[EQUIV_LOOP], 1.1174 + Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1.1175 + goto loser; 1.1176 + } 1.1177 + first = first->equiv; 1.1178 + if(!first->usesEquiv) { 1.1179 + break; 1.1180 + } 1.1181 + if(first == second) { 1.1182 + errStr = PR_smprintf(errString[EQUIV_LOOP], 1.1183 + Pk11Install_PlatformName_GetString(&_this->platforms[i].name)); 1.1184 + goto loser; 1.1185 + } 1.1186 + second = second->equiv; 1.1187 + first = first->equiv; 1.1188 + } 1.1189 + _this->platforms[i].equiv = first; 1.1190 + } 1.1191 + } 1.1192 + 1.1193 +loser: 1.1194 + if(iter) { 1.1195 + Pk11Install_ListIter_delete(iter); 1.1196 + PR_Free(iter); 1.1197 + iter = NULL; 1.1198 + } 1.1199 + if(subiter) { 1.1200 + Pk11Install_ListIter_delete(subiter); 1.1201 + PR_Free(subiter); 1.1202 + subiter = NULL; 1.1203 + } 1.1204 + return errStr; 1.1205 +} 1.1206 + 1.1207 +/* 1.1208 +////////////////////////////////////////////////////////////////////////// 1.1209 +// Method: GetBestPlatform 1.1210 +// Class: Pk11Install_Info 1.1211 +// Takes: char *myPlatform, the platform we are currently running 1.1212 +// on. 1.1213 +*/ 1.1214 +Pk11Install_Platform* 1.1215 +Pk11Install_Info_GetBestPlatform(Pk11Install_Info* _this, char *myPlatform) 1.1216 +{ 1.1217 + Pk11Install_PlatformName plat; 1.1218 + char *errStr; 1.1219 + int i, j; 1.1220 + 1.1221 + errStr=NULL; 1.1222 + 1.1223 + Pk11Install_PlatformName_init(&plat); 1.1224 + if( (errStr=Pk11Install_PlatformName_Generate(&plat, myPlatform)) ) { 1.1225 + PR_smprintf_free(errStr); 1.1226 + return NULL; 1.1227 + } 1.1228 + 1.1229 + /* First try real platforms */ 1.1230 + for(i=0; i < _this->numPlatforms; i++) { 1.1231 + if(Pk11Install_PlatformName_equal(&_this->platforms[i].name,&plat)) { 1.1232 + if(_this->platforms[i].equiv) { 1.1233 + return _this->platforms[i].equiv; 1.1234 + } 1.1235 + else { 1.1236 + return &_this->platforms[i]; 1.1237 + } 1.1238 + } 1.1239 + } 1.1240 + 1.1241 + /* Now try forward compatible platforms */ 1.1242 + for(i=0; i < _this->numForwardCompatible; i++) { 1.1243 + if(Pk11Install_PlatformName_lteq(&_this->forwardCompatible[i],&plat)) { 1.1244 + break; 1.1245 + } 1.1246 + } 1.1247 + if(i == _this->numForwardCompatible) { 1.1248 + return NULL; 1.1249 + } 1.1250 + 1.1251 + /* Got a forward compatible name, find the actual platform. */ 1.1252 + for(j=0; j < _this->numPlatforms; j++) { 1.1253 + if(Pk11Install_PlatformName_equal(&_this->platforms[j].name, 1.1254 + &_this->forwardCompatible[i])) { 1.1255 + if(_this->platforms[j].equiv) { 1.1256 + return _this->platforms[j].equiv; 1.1257 + } else { 1.1258 + return &_this->platforms[j]; 1.1259 + } 1.1260 + } 1.1261 + } 1.1262 + 1.1263 + return NULL; 1.1264 +} 1.1265 + 1.1266 +/* 1.1267 +////////////////////////////////////////////////////////////////////////// 1.1268 +// Method: Print 1.1269 +// Class: Pk11Install_Info 1.1270 +*/ 1.1271 +void 1.1272 +Pk11Install_Info_Print(Pk11Install_Info* _this, int pad) 1.1273 +{ 1.1274 + int i; 1.1275 + 1.1276 + PAD(pad); printf("Forward Compatible:\n"); 1.1277 + for(i = 0; i < _this->numForwardCompatible; i++) { 1.1278 + Pk11Install_PlatformName_Print(&_this->forwardCompatible[i],pad+PADINC); 1.1279 + PAD(pad); printf("-------------------\n"); 1.1280 + } 1.1281 + PAD(pad); printf("Platforms:\n"); 1.1282 + for( i = 0; i < _this->numPlatforms; i++) { 1.1283 + Pk11Install_Platform_Print(&_this->platforms[i],pad+PADINC); 1.1284 + PAD(pad); printf("-------------------\n"); 1.1285 + } 1.1286 +} 1.1287 + 1.1288 +/* 1.1289 +////////////////////////////////////////////////////////////////////////// 1.1290 +*/ 1.1291 +static char* 1.1292 +PR_Strdup(const char* str) 1.1293 +{ 1.1294 + char *tmp; 1.1295 + tmp = (char*) PR_Malloc((unsigned int)(strlen(str)+1)); 1.1296 + strcpy(tmp, str); 1.1297 + return tmp; 1.1298 +} 1.1299 + 1.1300 +/* The global value list, the top of the tree */ 1.1301 +Pk11Install_ValueList* Pk11Install_valueList=NULL; 1.1302 + 1.1303 +/****************************************************************************/ 1.1304 +void 1.1305 +Pk11Install_ValueList_AddItem(Pk11Install_ValueList* _this, 1.1306 + Pk11Install_Value *item) 1.1307 +{ 1.1308 + _this->numItems++; 1.1309 + if (item->type == STRING_VALUE) { 1.1310 + _this->numStrings++; 1.1311 + } else { 1.1312 + _this->numPairs++; 1.1313 + } 1.1314 + item->next = _this->head; 1.1315 + _this->head = item; 1.1316 +} 1.1317 + 1.1318 +/****************************************************************************/ 1.1319 +Pk11Install_ListIter* 1.1320 +Pk11Install_ListIter_new_default() 1.1321 +{ 1.1322 + Pk11Install_ListIter* new_this; 1.1323 + new_this = (Pk11Install_ListIter*) 1.1324 + PR_Malloc(sizeof(Pk11Install_ListIter)); 1.1325 + Pk11Install_ListIter_init(new_this); 1.1326 + return new_this; 1.1327 +} 1.1328 + 1.1329 +/****************************************************************************/ 1.1330 +void 1.1331 +Pk11Install_ListIter_init(Pk11Install_ListIter* _this) 1.1332 +{ 1.1333 + _this->list = NULL; 1.1334 + _this->current = NULL; 1.1335 +} 1.1336 + 1.1337 +/****************************************************************************/ 1.1338 +Pk11Install_ListIter* 1.1339 +Pk11Install_ListIter_new(const Pk11Install_ValueList *_list) 1.1340 +{ 1.1341 + Pk11Install_ListIter* new_this; 1.1342 + new_this = (Pk11Install_ListIter*) 1.1343 + PR_Malloc(sizeof(Pk11Install_ListIter)); 1.1344 + new_this->list = _list; 1.1345 + new_this->current = _list->head; 1.1346 + return new_this; 1.1347 +} 1.1348 + 1.1349 +/****************************************************************************/ 1.1350 +void 1.1351 +Pk11Install_ListIter_delete(Pk11Install_ListIter* _this) 1.1352 +{ 1.1353 + _this->list=NULL; 1.1354 + _this->current=NULL; 1.1355 +} 1.1356 + 1.1357 +/****************************************************************************/ 1.1358 +void 1.1359 +Pk11Install_ListIter_reset(Pk11Install_ListIter* _this) 1.1360 +{ 1.1361 + if(_this->list) { 1.1362 + _this->current = _this->list->head; 1.1363 + } 1.1364 +} 1.1365 + 1.1366 +/*************************************************************************/ 1.1367 +Pk11Install_Value* 1.1368 +Pk11Install_ListIter_nextItem(Pk11Install_ListIter* _this) 1.1369 +{ 1.1370 + if(_this->current) { 1.1371 + _this->current = _this->current->next; 1.1372 + } 1.1373 + 1.1374 + return _this->current; 1.1375 +} 1.1376 + 1.1377 +/****************************************************************************/ 1.1378 +Pk11Install_ValueList* 1.1379 +Pk11Install_ValueList_new() 1.1380 +{ 1.1381 + Pk11Install_ValueList* new_this; 1.1382 + new_this = (Pk11Install_ValueList*) 1.1383 + PR_Malloc(sizeof(Pk11Install_ValueList)); 1.1384 + new_this->numItems = 0; 1.1385 + new_this->numPairs = 0; 1.1386 + new_this->numStrings = 0; 1.1387 + new_this->head = NULL; 1.1388 + return new_this; 1.1389 +} 1.1390 + 1.1391 +/****************************************************************************/ 1.1392 +void 1.1393 +Pk11Install_ValueList_delete(Pk11Install_ValueList* _this) 1.1394 +{ 1.1395 + 1.1396 + Pk11Install_Value *tmp; 1.1397 + Pk11Install_Value *list; 1.1398 + list = _this->head; 1.1399 + 1.1400 + while(list != NULL) { 1.1401 + tmp = list; 1.1402 + list = list->next; 1.1403 + PR_Free(tmp); 1.1404 + } 1.1405 + PR_Free(_this); 1.1406 +} 1.1407 + 1.1408 +/****************************************************************************/ 1.1409 +Pk11Install_Value* 1.1410 +Pk11Install_Value_new_default() 1.1411 +{ 1.1412 + Pk11Install_Value* new_this; 1.1413 + new_this = (Pk11Install_Value*)PR_Malloc(sizeof(Pk11Install_Value)); 1.1414 + new_this->type = STRING_VALUE; 1.1415 + new_this->string = NULL; 1.1416 + new_this->pair = NULL; 1.1417 + new_this->next = NULL; 1.1418 + return new_this; 1.1419 +} 1.1420 + 1.1421 +/****************************************************************************/ 1.1422 +Pk11Install_Value* 1.1423 +Pk11Install_Value_new(ValueType _type, Pk11Install_Pointer ptr) 1.1424 +{ 1.1425 + Pk11Install_Value* new_this; 1.1426 + new_this = Pk11Install_Value_new_default(); 1.1427 + new_this->type = _type; 1.1428 + if(_type == STRING_VALUE) { 1.1429 + new_this->pair = NULL; 1.1430 + new_this->string = ptr.string; 1.1431 + } else { 1.1432 + new_this->string = NULL; 1.1433 + new_this->pair = ptr.pair; 1.1434 + } 1.1435 + return new_this; 1.1436 +} 1.1437 + 1.1438 +/****************************************************************************/ 1.1439 +void 1.1440 +Pk11Install_Value_delete(Pk11Install_Value* _this) 1.1441 +{ 1.1442 + if(_this->type == STRING_VALUE) { 1.1443 + PR_Free(_this->string); 1.1444 + } else { 1.1445 + PR_Free(_this->pair); 1.1446 + } 1.1447 +} 1.1448 + 1.1449 +/****************************************************************************/ 1.1450 +Pk11Install_Pair* 1.1451 +Pk11Install_Pair_new_default() 1.1452 +{ 1.1453 + return Pk11Install_Pair_new(NULL,NULL); 1.1454 +} 1.1455 + 1.1456 +/****************************************************************************/ 1.1457 +Pk11Install_Pair* 1.1458 +Pk11Install_Pair_new(char *_key, Pk11Install_ValueList *_list) 1.1459 +{ 1.1460 + Pk11Install_Pair* new_this; 1.1461 + new_this = (Pk11Install_Pair*)PR_Malloc(sizeof(Pk11Install_Pair)); 1.1462 + new_this->key = _key; 1.1463 + new_this->list = _list; 1.1464 + return new_this; 1.1465 +} 1.1466 + 1.1467 +/****************************************************************************/ 1.1468 +void 1.1469 +Pk11Install_Pair_delete(Pk11Install_Pair* _this) 1.1470 +{ 1.1471 + PR_Free(_this->key); 1.1472 + Pk11Install_ValueList_delete(_this->list); 1.1473 + PR_Free(_this->list); 1.1474 +} 1.1475 + 1.1476 +/*************************************************************************/ 1.1477 +void 1.1478 +Pk11Install_Pair_Print(Pk11Install_Pair* _this, int pad) 1.1479 +{ 1.1480 + while (_this) { 1.1481 + /*PAD(pad); printf("**Pair\n"); 1.1482 + PAD(pad); printf("***Key====\n");*/ 1.1483 + PAD(pad); printf("%s {\n", _this->key); 1.1484 + /*PAD(pad); printf("====\n");*/ 1.1485 + /*PAD(pad); printf("***ValueList\n");*/ 1.1486 + Pk11Install_ValueList_Print(_this->list,pad+PADINC); 1.1487 + PAD(pad); printf("}\n"); 1.1488 + } 1.1489 +} 1.1490 + 1.1491 +/*************************************************************************/ 1.1492 +void 1.1493 +Pk11Install_ValueList_Print(Pk11Install_ValueList* _this, int pad) 1.1494 +{ 1.1495 + Pk11Install_Value *v; 1.1496 + 1.1497 + /*PAD(pad);printf("**Value List**\n");*/ 1.1498 + for(v = _this->head; v != NULL; v=v->next) { 1.1499 + Pk11Install_Value_Print(v,pad); 1.1500 + } 1.1501 +} 1.1502 + 1.1503 +/*************************************************************************/ 1.1504 +void 1.1505 +Pk11Install_Value_Print(Pk11Install_Value* _this, int pad) 1.1506 +{ 1.1507 + /*PAD(pad); printf("**Value, type=%s\n", 1.1508 + type==STRING_VALUE ? "string" : "pair");*/ 1.1509 + if(_this->type==STRING_VALUE) { 1.1510 + /*PAD(pad+PADINC); printf("====\n");*/ 1.1511 + PAD(pad); printf("%s\n", _this->string); 1.1512 + /*PAD(pad+PADINC); printf("====\n");*/ 1.1513 + } else { 1.1514 + Pk11Install_Pair_Print(_this->pair,pad+PADINC); 1.1515 + } 1.1516 +}