1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "install-ds.h"
11 #define PORT_Strcasecmp PL_strcasecmp
13 #define MODULE_FILE_STRING "ModuleFile"
14 #define MODULE_NAME_STRING "ModuleName"
15 #define MECH_FLAGS_STRING "DefaultMechanismFlags"
16 #define CIPHER_FLAGS_STRING "DefaultCipherFlags"
17 #define FILES_STRING "Files"
18 #define FORWARD_COMPATIBLE_STRING "ForwardCompatible"
19 #define PLATFORMS_STRING "Platforms"
20 #define RELATIVE_DIR_STRING "RelativePath"
21 #define ABSOLUTE_DIR_STRING "AbsolutePath"
22 #define FILE_PERMISSIONS_STRING "FilePermissions"
23 #define EQUIVALENT_PLATFORM_STRING "EquivalentPlatform"
24 #define EXECUTABLE_STRING "Executable"
26 #define DEFAULT_PERMISSIONS 0777
28 #define PLATFORM_SEPARATOR_CHAR ':'
34 BOGUS_FILE_PERMISSIONS,
37 EMPTY_PLATFORM_STRING,
38 BOGUS_PLATFORM_STRING,
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"
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"
89 static char* PR_Strdup(const char* str);
91 #define PAD(x) {int i; for(i=0;i<x;i++) printf(" ");}
95 Pk11Install_File_new()
97 Pk11Install_File* new_this;
98 new_this = (Pk11Install_File*)PR_Malloc(sizeof(Pk11Install_File));
99 Pk11Install_File_init(new_this);
104 Pk11Install_File_init(Pk11Install_File* _this)
107 _this->relativePath=NULL;
108 _this->absolutePath=NULL;
109 _this->executable=PR_FALSE;
110 _this->permissions=0;
114 //////////////////////////////////////////////////////////////////////////
115 // Method: ~Pk11Install_File
116 // Class: Pk11Install_File
117 // Notes: Destructor.
120 Pk11Install_File_delete(Pk11Install_File* _this)
122 Pk11Install_File_Cleanup(_this);
126 //////////////////////////////////////////////////////////////////////////
128 // Class: Pk11Install_File
131 Pk11Install_File_Cleanup(Pk11Install_File* _this)
134 PR_Free(_this->jarPath);
135 _this->jarPath = NULL;
137 if(_this->relativePath) {
138 PR_Free(_this->relativePath);
139 _this->relativePath = NULL;
141 if(_this->absolutePath) {
142 PR_Free(_this->absolutePath);
143 _this->absolutePath = NULL;
146 _this->permissions = 0;
147 _this->executable = PR_FALSE;
151 //////////////////////////////////////////////////////////////////////////
153 // Class: Pk11Install_File
154 // Notes: Creates a file data structure from a syntax tree.
155 // Returns: NULL for success, otherwise an error message.
158 Pk11Install_File_Generate(Pk11Install_File* _this,
159 const Pk11Install_Pair *pair)
161 Pk11Install_ListIter *iter;
162 Pk11Install_Value *val;
163 Pk11Install_Pair *subpair;
164 Pk11Install_ListIter *subiter;
165 Pk11Install_Value *subval;
175 /* Clear out old values */
176 Pk11Install_File_Cleanup(_this);
178 _this->jarPath = PR_Strdup(pair->key);
180 /* Go through all the pairs under this file heading */
181 iter = Pk11Install_ListIter_new(pair->list);
182 for( ; (val = iter->current); Pk11Install_ListIter_nextItem(iter)) {
183 if(val->type == PAIR_VALUE) {
186 /* Relative directory */
187 if(!PORT_Strcasecmp(subpair->key, RELATIVE_DIR_STRING)) {
188 subiter = Pk11Install_ListIter_new(subpair->list);
189 subval = subiter->current;
190 if(!subval || (subval->type != STRING_VALUE)){
191 errStr = PR_smprintf(errString[BOGUS_RELATIVE_DIR],
195 _this->relativePath = PR_Strdup(subval->string);
196 Pk11Install_ListIter_delete(subiter);
199 /* Absolute directory */
200 } else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
201 subiter = Pk11Install_ListIter_new(subpair->list);
202 subval = subiter->current;
203 if(!subval || (subval->type != STRING_VALUE)){
204 errStr = PR_smprintf(errString[BOGUS_ABSOLUTE_DIR],
208 _this->absolutePath = PR_Strdup(subval->string);
209 Pk11Install_ListIter_delete(subiter);
212 /* file permissions */
213 } else if( !PORT_Strcasecmp(subpair->key,
214 FILE_PERMISSIONS_STRING)) {
215 subiter = Pk11Install_ListIter_new(subpair->list);
216 subval = subiter->current;
217 if(!subval || (subval->type != STRING_VALUE)){
218 errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
222 _this->permissions = (int) strtol(subval->string, &endp, 8);
223 if(*endp != '\0' || subval->string == "\0") {
224 errStr = PR_smprintf(errString[BOGUS_FILE_PERMISSIONS],
229 Pk11Install_ListIter_delete(subiter);
233 if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
234 _this->executable = PR_TRUE;
239 /* Default permission value */
241 _this->permissions = DEFAULT_PERMISSIONS;
244 /* Make sure we got all the information */
245 if(!_this->relativePath && !_this->absolutePath) {
246 errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath);
250 if(!_this->relativePath ) {
251 errStr = PR_smprintf(errString[NO_RELATIVE_DIR], _this->jarPath);
254 if(!_this->absolutePath) {
255 errStr = PR_smprintf(errString[NO_ABSOLUTE_DIR], _this->jarPath);
262 Pk11Install_ListIter_delete(iter);
266 Pk11Install_ListIter_delete(subiter);
273 //////////////////////////////////////////////////////////////////////////
275 // Class: Pk11Install_File
278 Pk11Install_File_Print(Pk11Install_File* _this, int pad)
280 PAD(pad); printf("jarPath: %s\n",
281 _this->jarPath ? _this->jarPath : "<NULL>");
282 PAD(pad); printf("relativePath: %s\n",
283 _this->relativePath ? _this->relativePath: "<NULL>");
284 PAD(pad); printf("absolutePath: %s\n",
285 _this->absolutePath ? _this->absolutePath: "<NULL>");
286 PAD(pad); printf("permissions: %o\n", _this->permissions);
289 Pk11Install_PlatformName*
290 Pk11Install_PlatformName_new()
292 Pk11Install_PlatformName* new_this;
293 new_this = (Pk11Install_PlatformName*)
294 PR_Malloc(sizeof(Pk11Install_PlatformName));
295 Pk11Install_PlatformName_init(new_this);
300 Pk11Install_PlatformName_init(Pk11Install_PlatformName* _this)
303 _this->verString = NULL;
304 _this->numDigits = 0;
309 //////////////////////////////////////////////////////////////////////////
310 // Method: ~Pk11Install_PlatformName
311 // Class: Pk11Install_PlatformName
314 Pk11Install_PlatformName_delete(Pk11Install_PlatformName* _this)
316 Pk11Install_PlatformName_Cleanup(_this);
320 //////////////////////////////////////////////////////////////////////////
322 // Class: Pk11Install_PlatformName
325 Pk11Install_PlatformName_Cleanup(Pk11Install_PlatformName* _this)
331 if(_this->verString) {
333 for (i=0; i<_this->numDigits; i++) {
334 PR_Free(_this->verString[i]);
336 PR_Free(_this->verString);
337 _this->verString = NULL;
340 PR_Free(_this->arch);
343 _this->numDigits = 0;
347 //////////////////////////////////////////////////////////////////////////
349 // Class: Pk11Install_PlatformName
350 // Notes: Extracts the information from a platform string.
353 Pk11Install_PlatformName_Generate(Pk11Install_PlatformName* _this,
358 char *end, *start; /* start and end of a section (OS, version, arch)*/
359 char *pend, *pstart; /* start and end of one portion of version*/
360 char *endp; /* used by strtol*/
367 errStr = PR_smprintf(errString[EMPTY_PLATFORM_STRING]);
370 copy = PR_Strdup(str);
375 end = strchr(copy, PLATFORM_SEPARATOR_CHAR);
376 if(!end || end==copy) {
377 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
382 _this->OS = PR_Strdup(copy);
385 // Get the digits of the version of form: x.x.x (arbitrary number of digits)
389 end = strchr(start, PLATFORM_SEPARATOR_CHAR);
391 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
397 /* Find out how many periods*/
400 while( (pend=strchr(pstart, '.')) ) {
404 _this->numDigits= 1+ periods;
405 _this->verString = (char**)PR_Malloc(sizeof(char*)*_this->numDigits);
409 /* Get the digits before each period*/
410 while( (pend=strchr(pstart, '.')) ) {
412 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
416 _this->verString[i] = PR_Strdup(pstart);
418 if(endp==pstart || (*endp != '\0')) {
419 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
425 /* Last digit comes after the last period*/
426 if(*pstart == '\0') {
427 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
430 _this->verString[i] = PR_Strdup(pstart);
432 if(endp==pstart || (*endp != '\0')) {
433 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
438 _this->verString = NULL;
439 _this->numDigits = 0;
443 // Get the architecture
446 if( strchr(start, PLATFORM_SEPARATOR_CHAR) ) {
447 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
450 _this->arch = PR_Strdup(start);
461 if(_this->verString) {
462 for (i=0; i<_this->numDigits; i++) {
463 PR_Free(_this->verString[i]);
465 PR_Free(_this->verString);
466 _this->verString = NULL;
468 _this->numDigits = 0;
470 PR_Free(_this->arch);
478 //////////////////////////////////////////////////////////////////////////
479 // Method: operator ==
480 // Class: Pk11Install_PlatformName
481 // Returns: PR_TRUE if the platform have the same OS, arch, and version
484 Pk11Install_PlatformName_equal(Pk11Install_PlatformName* _this,
485 Pk11Install_PlatformName* cmp)
489 if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) {
493 if( PORT_Strcasecmp(_this->OS, cmp->OS) ||
494 PORT_Strcasecmp(_this->arch, cmp->arch) ||
495 _this->numDigits != cmp->numDigits ) {
499 for(i=0; i < _this->numDigits; i++) {
500 if(PORT_Strcasecmp(_this->verString[i], cmp->verString[i])) {
508 //////////////////////////////////////////////////////////////////////////
509 // Method: operator <=
510 // Class: Pk11Install_PlatformName
511 // Returns: PR_TRUE if the platform have the same OS and arch and a lower
515 Pk11Install_PlatformName_lteq(Pk11Install_PlatformName* _this,
516 Pk11Install_PlatformName* cmp)
518 return (Pk11Install_PlatformName_equal(_this,cmp) ||
519 Pk11Install_PlatformName_lt(_this,cmp)) ? PR_TRUE : PR_FALSE;
523 //////////////////////////////////////////////////////////////////////////
524 // Method: operator <
525 // Class: Pk11Install_PlatformName
526 // Returns: PR_TRUE if the platform have the same OS and arch and a greater
530 Pk11Install_PlatformName_lt(Pk11Install_PlatformName* _this,
531 Pk11Install_PlatformName* cmp)
535 if(!_this->OS || !_this->arch || !cmp->OS || !cmp->arch) {
539 if( PORT_Strcasecmp(_this->OS, cmp->OS) ) {
542 if( PORT_Strcasecmp(_this->arch, cmp->arch) ) {
546 for(i=0; (i < _this->numDigits) && (i < cmp->numDigits); i++) {
547 scmp = PORT_Strcasecmp(_this->verString[i], cmp->verString[i]);
550 } else if (scmp < 0) {
554 /* All the digits they have in common are the same. */
555 if(_this->numDigits < cmp->numDigits) {
563 //////////////////////////////////////////////////////////////////////////
565 // Class: Pk11Install_PlatformName
566 // Returns: String composed of OS, release, and architecture separated
567 // by the separator char. Memory is allocated by this function
568 // but is the responsibility of the caller to de-allocate.
571 Pk11Install_PlatformName_GetString(Pk11Install_PlatformName* _this)
581 OS_ = _this->OS ? _this->OS : "";
582 arch_ = _this->arch ? _this->arch : "";
584 ver = Pk11Install_PlatformName_GetVerString(_this);
585 ret = PR_smprintf("%s%c%s%c%s", OS_, PLATFORM_SEPARATOR_CHAR, ver,
586 PLATFORM_SEPARATOR_CHAR, arch_);
594 //////////////////////////////////////////////////////////////////////////
595 // Method: GetVerString
596 // Class: Pk11Install_PlatformName
597 // Returns: The version string for this platform, in the form x.x.x with an
598 // arbitrary number of digits. Memory allocated by function,
599 // must be de-allocated by caller.
602 Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this)
609 tmp = (char*)PR_Malloc(80*_this->numDigits+1);
612 for(i=0; i < _this->numDigits-1; i++) {
613 sprintf(buf, "%s.", _this->verString[i]);
616 if(i < _this->numDigits) {
617 sprintf(buf, "%s", _this->verString[i]);
621 ret = PR_Strdup(tmp);
628 //////////////////////////////////////////////////////////////////////////
630 // Class: Pk11Install_PlatformName
633 Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad)
635 PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>");
636 PAD(pad); printf("Digits: ");
637 if(_this->numDigits == 0) {
640 printf("%s\n", Pk11Install_PlatformName_GetVerString(_this));
642 PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>");
645 Pk11Install_Platform*
646 Pk11Install_Platform_new()
648 Pk11Install_Platform* new_this;
649 new_this = (Pk11Install_Platform*)PR_Malloc(sizeof(Pk11Install_Platform));
650 Pk11Install_Platform_init(new_this);
655 Pk11Install_Platform_init(Pk11Install_Platform* _this)
657 Pk11Install_PlatformName_init(&_this->name);
658 Pk11Install_PlatformName_init(&_this->equivName);
660 _this->usesEquiv = PR_FALSE;
661 _this->moduleFile = NULL;
662 _this->moduleName = NULL;
664 _this->mechFlags = 0;
665 _this->cipherFlags = 0;
671 //////////////////////////////////////////////////////////////////////////
672 // Method: ~Pk11Install_Platform
673 // Class: Pk11Install_Platform
676 Pk11Install_Platform_delete(Pk11Install_Platform* _this)
678 Pk11Install_Platform_Cleanup(_this);
682 //////////////////////////////////////////////////////////////////////////
684 // Class: Pk11Install_Platform
687 Pk11Install_Platform_Cleanup(Pk11Install_Platform* _this)
690 if(_this->moduleFile) {
691 PR_Free(_this->moduleFile);
692 _this->moduleFile = NULL;
694 if(_this->moduleName) {
695 PR_Free(_this->moduleName);
696 _this->moduleName = NULL;
699 for (i=0;i<_this->numFiles;i++) {
700 Pk11Install_File_delete(&_this->files[i]);
702 PR_Free(_this->files);
706 _this->usesEquiv = PR_FALSE;
709 _this->mechFlags = _this->cipherFlags = 0;
713 //////////////////////////////////////////////////////////////////////////
715 // Class: Pk11Install_Platform
716 // Notes: Creates a platform data structure from a syntax tree.
717 // Returns: NULL for success, otherwise an error message.
720 Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
721 const Pk11Install_Pair *pair)
727 Pk11Install_ListIter *iter;
728 Pk11Install_Value *val;
729 Pk11Install_Value *subval;
730 Pk11Install_Pair *subpair;
731 Pk11Install_ListIter *subiter;
732 PRBool gotModuleFile, gotModuleName, gotMech,
733 gotCipher, gotFiles, gotEquiv;
739 gotModuleFile=gotModuleName=gotMech=gotCipher=gotFiles=gotEquiv=PR_FALSE;
740 Pk11Install_Platform_Cleanup(_this);
742 errStr = Pk11Install_PlatformName_Generate(&_this->name,pair->key);
744 tmp = PR_smprintf("%s: %s", pair->key, errStr);
745 PR_smprintf_free(errStr);
750 iter = Pk11Install_ListIter_new(pair->list);
751 for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) {
752 if(val->type==PAIR_VALUE) {
755 if( !PORT_Strcasecmp(subpair->key, MODULE_FILE_STRING)) {
757 errStr = PR_smprintf(errString[REPEAT_MODULE_FILE],
758 Pk11Install_PlatformName_GetString(&_this->name));
761 subiter = Pk11Install_ListIter_new(subpair->list);
762 subval = subiter->current;
763 if(!subval || (subval->type != STRING_VALUE)) {
764 errStr = PR_smprintf(errString[BOGUS_MODULE_FILE],
765 Pk11Install_PlatformName_GetString(&_this->name));
768 _this->moduleFile = PR_Strdup(subval->string);
769 Pk11Install_ListIter_delete(subiter);
772 gotModuleFile = PR_TRUE;
773 } else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
775 errStr = PR_smprintf(errString[REPEAT_MODULE_NAME],
776 Pk11Install_PlatformName_GetString(&_this->name));
779 subiter = Pk11Install_ListIter_new(subpair->list);
780 subval = subiter->current;
781 if(!subval || (subval->type != STRING_VALUE)) {
782 errStr = PR_smprintf(errString[BOGUS_MODULE_NAME],
783 Pk11Install_PlatformName_GetString(&_this->name));
786 _this->moduleName = PR_Strdup(subval->string);
787 Pk11Install_ListIter_delete(subiter);
790 gotModuleName = PR_TRUE;
791 } else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
795 errStr = PR_smprintf(errString[REPEAT_MECH],
796 Pk11Install_PlatformName_GetString(&_this->name));
799 subiter = Pk11Install_ListIter_new(subpair->list);
800 subval = subiter->current;
801 if(!subval || (subval->type != STRING_VALUE)) {
802 errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS],
803 Pk11Install_PlatformName_GetString(&_this->name));
806 _this->mechFlags = strtol(subval->string, &endptr, 0);
807 if(*endptr!='\0' || (endptr==subval->string) ) {
808 errStr = PR_smprintf(errString[BOGUS_MECH_FLAGS],
809 Pk11Install_PlatformName_GetString(&_this->name));
812 Pk11Install_ListIter_delete(subiter);
816 } else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
820 errStr = PR_smprintf(errString[REPEAT_CIPHER],
821 Pk11Install_PlatformName_GetString(&_this->name));
824 subiter = Pk11Install_ListIter_new(subpair->list);
825 subval = subiter->current;
826 if(!subval || (subval->type != STRING_VALUE)) {
827 errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS],
828 Pk11Install_PlatformName_GetString(&_this->name));
831 _this->cipherFlags = strtol(subval->string, &endptr, 0);
832 if(*endptr!='\0' || (endptr==subval->string) ) {
833 errStr = PR_smprintf(errString[BOGUS_CIPHER_FLAGS],
834 Pk11Install_PlatformName_GetString(&_this->name));
837 Pk11Install_ListIter_delete(subiter);
841 } else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
843 errStr = PR_smprintf(errString[REPEAT_FILES],
844 Pk11Install_PlatformName_GetString(&_this->name));
847 subiter = Pk11Install_ListIter_new(subpair->list);
848 _this->numFiles = subpair->list->numPairs;
849 _this->files = (Pk11Install_File*)
850 PR_Malloc(sizeof(Pk11Install_File)*_this->numFiles);
851 for(i=0; i < _this->numFiles; i++,
852 Pk11Install_ListIter_nextItem(subiter)) {
853 Pk11Install_File_init(&_this->files[i]);
854 val = subiter->current;
855 if(val && (val->type==PAIR_VALUE)) {
856 errStr = Pk11Install_File_Generate(&_this->files[i],val->pair);
858 tmp = PR_smprintf("%s: %s",
859 Pk11Install_PlatformName_GetString(&_this->name),errStr);
860 PR_smprintf_free(errStr);
867 } else if(!PORT_Strcasecmp(subpair->key,
868 EQUIVALENT_PLATFORM_STRING)) {
870 errStr = PR_smprintf(errString[REPEAT_EQUIV],
871 Pk11Install_PlatformName_GetString(&_this->name));
874 subiter = Pk11Install_ListIter_new(subpair->list);
875 subval = subiter->current;
876 if(!subval || (subval->type != STRING_VALUE) ) {
877 errStr = PR_smprintf(errString[BOGUS_EQUIV],
878 Pk11Install_PlatformName_GetString(&_this->name));
881 errStr = Pk11Install_PlatformName_Generate(&_this->equivName,
884 tmp = PR_smprintf("%s: %s",
885 Pk11Install_PlatformName_GetString(&_this->name), errStr);
886 tmp = PR_smprintf("%s: %s",
887 Pk11Install_PlatformName_GetString(&_this->name), errStr);
888 PR_smprintf_free(errStr);
892 _this->usesEquiv = PR_TRUE;
897 /* Make sure we either have an EquivalentPlatform or all the other info */
898 if(_this->usesEquiv &&
899 (gotFiles || gotModuleFile || gotModuleName || gotMech || gotCipher)) {
900 errStr = PR_smprintf(errString[EQUIV_TOO_MUCH_INFO],
901 Pk11Install_PlatformName_GetString(&_this->name));
904 if(!gotFiles && !_this->usesEquiv) {
905 errStr = PR_smprintf(errString[NO_FILES],
906 Pk11Install_PlatformName_GetString(&_this->name));
909 if(!gotModuleFile && !_this->usesEquiv) {
910 errStr= PR_smprintf(errString[NO_MODULE_FILE],
911 Pk11Install_PlatformName_GetString(&_this->name));
914 if(!gotModuleName && !_this->usesEquiv) {
915 errStr = PR_smprintf(errString[NO_MODULE_NAME],
916 Pk11Install_PlatformName_GetString(&_this->name));
920 /* Point the modFile pointer to the correct file */
922 for(i=0; i < _this->numFiles; i++) {
923 if(!PORT_Strcasecmp(_this->moduleFile, _this->files[i].jarPath) ) {
928 if(_this->modFile==-1) {
929 errStr = PR_smprintf(errString[UNKNOWN_MODULE_FILE],
931 Pk11Install_PlatformName_GetString(&_this->name));
947 //////////////////////////////////////////////////////////////////////////
949 // Class: Pk11Install_Platform
952 Pk11Install_Platform_Print(Pk11Install_Platform* _this, int pad)
956 PAD(pad); printf("Name:\n");
957 Pk11Install_PlatformName_Print(&_this->name,pad+PADINC);
958 PAD(pad); printf("equivName:\n");
959 Pk11Install_PlatformName_Print(&_this->equivName,pad+PADINC);
961 if(_this->usesEquiv) {
962 printf("Uses equiv, which points to:\n");
963 Pk11Install_Platform_Print(_this->equiv,pad+PADINC);
965 printf("Doesn't use equiv\n");
968 printf("Module File: %s\n", _this->moduleFile ? _this->moduleFile
970 PAD(pad); printf("mechFlags: %lx\n", _this->mechFlags);
971 PAD(pad); printf("cipherFlags: %lx\n", _this->cipherFlags);
972 PAD(pad); printf("Files:\n");
973 for(i=0; i < _this->numFiles; i++) {
974 Pk11Install_File_Print(&_this->files[i],pad+PADINC);
975 PAD(pad); printf("--------------------\n");
980 //////////////////////////////////////////////////////////////////////////
981 // Method: Pk11Install_Info
982 // Class: Pk11Install_Info
985 Pk11Install_Info_new()
987 Pk11Install_Info* new_this;
988 new_this = (Pk11Install_Info*)PR_Malloc(sizeof(Pk11Install_Info));
989 Pk11Install_Info_init(new_this);
994 Pk11Install_Info_init(Pk11Install_Info* _this)
996 _this->platforms = NULL;
997 _this->numPlatforms = 0;
998 _this->forwardCompatible = NULL;
999 _this->numForwardCompatible = 0;
1003 //////////////////////////////////////////////////////////////////////////
1004 // Method: ~Pk11Install_Info
1005 // Class: Pk11Install_Info
1008 Pk11Install_Info_delete(Pk11Install_Info* _this)
1010 Pk11Install_Info_Cleanup(_this);
1014 //////////////////////////////////////////////////////////////////////////
1016 // Class: Pk11Install_Info
1019 Pk11Install_Info_Cleanup(Pk11Install_Info* _this)
1022 if(_this->platforms) {
1023 for (i=0;i<_this->numPlatforms;i++) {
1024 Pk11Install_Platform_delete(&_this->platforms[i]);
1026 PR_Free(&_this->platforms);
1027 _this->platforms = NULL;
1028 _this->numPlatforms = 0;
1031 if(_this->forwardCompatible) {
1032 for (i=0;i<_this->numForwardCompatible;i++) {
1033 Pk11Install_PlatformName_delete(&_this->forwardCompatible[i]);
1035 PR_Free(&_this->forwardCompatible);
1036 _this->numForwardCompatible = 0;
1041 //////////////////////////////////////////////////////////////////////////
1043 // Class: Pk11Install_Info
1044 // Takes: Pk11Install_ValueList *list, the top-level list
1045 // resulting from parsing an installer file.
1046 // Returns: char*, NULL if successful, otherwise an error string.
1047 // Caller is responsible for freeing memory.
1050 Pk11Install_Info_Generate(Pk11Install_Info* _this,
1051 const Pk11Install_ValueList *list)
1054 Pk11Install_ListIter *iter;
1055 Pk11Install_Value *val;
1056 Pk11Install_Pair *pair;
1057 Pk11Install_ListIter *subiter;
1058 Pk11Install_Value *subval;
1059 Pk11Install_Platform *first, *second;
1064 Pk11Install_Info_Cleanup(_this);
1066 iter = Pk11Install_ListIter_new(list);
1067 for( ; (val=iter->current); Pk11Install_ListIter_nextItem(iter)) {
1068 if(val->type == PAIR_VALUE) {
1071 if(!PORT_Strcasecmp(pair->key, FORWARD_COMPATIBLE_STRING)) {
1072 subiter = Pk11Install_ListIter_new(pair->list);
1073 _this->numForwardCompatible = pair->list->numStrings;
1074 _this->forwardCompatible = (Pk11Install_PlatformName*)
1075 PR_Malloc(sizeof(Pk11Install_PlatformName)*
1076 _this->numForwardCompatible);
1077 for(i=0; i < _this->numForwardCompatible; i++,
1078 Pk11Install_ListIter_nextItem(subiter)) {
1079 subval = subiter->current;
1080 if(subval->type == STRING_VALUE) {
1081 errStr = Pk11Install_PlatformName_Generate(
1082 &_this->forwardCompatible[i], subval->string);
1088 Pk11Install_ListIter_delete(subiter);
1091 } else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
1092 subiter = Pk11Install_ListIter_new(pair->list);
1093 _this->numPlatforms = pair->list->numPairs;
1094 _this->platforms = (Pk11Install_Platform*)
1095 PR_Malloc(sizeof(Pk11Install_Platform)*
1096 _this->numPlatforms);
1097 for(i=0; i < _this->numPlatforms; i++,
1098 Pk11Install_ListIter_nextItem(subiter)) {
1099 Pk11Install_Platform_init(&_this->platforms[i]);
1100 subval = subiter->current;
1101 if(subval->type == PAIR_VALUE) {
1102 errStr = Pk11Install_Platform_Generate(&_this->platforms[i],subval->pair);
1108 Pk11Install_ListIter_delete(subiter);
1115 if(_this->numPlatforms == 0) {
1116 errStr = PR_smprintf(errString[NO_PLATFORMS]);
1122 // Now process equivalent platforms
1125 // First the naive pass
1127 for(i=0; i < _this->numPlatforms; i++) {
1128 if(_this->platforms[i].usesEquiv) {
1129 _this->platforms[i].equiv = NULL;
1130 for(j=0; j < _this->numPlatforms; j++) {
1131 if (Pk11Install_PlatformName_equal(&_this->platforms[i].equivName,
1132 &_this->platforms[j].name)) {
1134 errStr = PR_smprintf(errString[EQUIV_LOOP],
1135 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1138 _this->platforms[i].equiv = &_this->platforms[j];
1142 if(_this->platforms[i].equiv == NULL) {
1143 errStr = PR_smprintf(errString[BOGUS_EQUIV],
1144 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1151 // Now the intelligent pass, which will also detect loops.
1152 // We will send two pointers through the linked list of equivalent
1153 // platforms. Both start with the current node. "first" traverses
1154 // two nodes for each iteration. "second" lags behind, only traversing
1155 // one node per iteration. Eventually one of two things will happen:
1156 // first will hit the end of the list (a platform that doesn't use
1157 // an equivalency), or first will equal second if there is a loop.
1159 for(i=0; i < _this->numPlatforms; i++) {
1160 if(_this->platforms[i].usesEquiv) {
1161 second = _this->platforms[i].equiv;
1162 if(!second->usesEquiv) {
1163 /* The first link is the terminal node */
1166 first = second->equiv;
1167 while(first->usesEquiv) {
1168 if(first == second) {
1169 errStr = PR_smprintf(errString[EQUIV_LOOP],
1170 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1173 first = first->equiv;
1174 if(!first->usesEquiv) {
1177 if(first == second) {
1178 errStr = PR_smprintf(errString[EQUIV_LOOP],
1179 Pk11Install_PlatformName_GetString(&_this->platforms[i].name));
1182 second = second->equiv;
1183 first = first->equiv;
1185 _this->platforms[i].equiv = first;
1191 Pk11Install_ListIter_delete(iter);
1196 Pk11Install_ListIter_delete(subiter);
1204 //////////////////////////////////////////////////////////////////////////
1205 // Method: GetBestPlatform
1206 // Class: Pk11Install_Info
1207 // Takes: char *myPlatform, the platform we are currently running
1210 Pk11Install_Platform*
1211 Pk11Install_Info_GetBestPlatform(Pk11Install_Info* _this, char *myPlatform)
1213 Pk11Install_PlatformName plat;
1219 Pk11Install_PlatformName_init(&plat);
1220 if( (errStr=Pk11Install_PlatformName_Generate(&plat, myPlatform)) ) {
1221 PR_smprintf_free(errStr);
1225 /* First try real platforms */
1226 for(i=0; i < _this->numPlatforms; i++) {
1227 if(Pk11Install_PlatformName_equal(&_this->platforms[i].name,&plat)) {
1228 if(_this->platforms[i].equiv) {
1229 return _this->platforms[i].equiv;
1232 return &_this->platforms[i];
1237 /* Now try forward compatible platforms */
1238 for(i=0; i < _this->numForwardCompatible; i++) {
1239 if(Pk11Install_PlatformName_lteq(&_this->forwardCompatible[i],&plat)) {
1243 if(i == _this->numForwardCompatible) {
1247 /* Got a forward compatible name, find the actual platform. */
1248 for(j=0; j < _this->numPlatforms; j++) {
1249 if(Pk11Install_PlatformName_equal(&_this->platforms[j].name,
1250 &_this->forwardCompatible[i])) {
1251 if(_this->platforms[j].equiv) {
1252 return _this->platforms[j].equiv;
1254 return &_this->platforms[j];
1263 //////////////////////////////////////////////////////////////////////////
1265 // Class: Pk11Install_Info
1268 Pk11Install_Info_Print(Pk11Install_Info* _this, int pad)
1272 PAD(pad); printf("Forward Compatible:\n");
1273 for(i = 0; i < _this->numForwardCompatible; i++) {
1274 Pk11Install_PlatformName_Print(&_this->forwardCompatible[i],pad+PADINC);
1275 PAD(pad); printf("-------------------\n");
1277 PAD(pad); printf("Platforms:\n");
1278 for( i = 0; i < _this->numPlatforms; i++) {
1279 Pk11Install_Platform_Print(&_this->platforms[i],pad+PADINC);
1280 PAD(pad); printf("-------------------\n");
1285 //////////////////////////////////////////////////////////////////////////
1288 PR_Strdup(const char* str)
1291 tmp = (char*) PR_Malloc((unsigned int)(strlen(str)+1));
1296 /* The global value list, the top of the tree */
1297 Pk11Install_ValueList* Pk11Install_valueList=NULL;
1299 /****************************************************************************/
1301 Pk11Install_ValueList_AddItem(Pk11Install_ValueList* _this,
1302 Pk11Install_Value *item)
1305 if (item->type == STRING_VALUE) {
1306 _this->numStrings++;
1310 item->next = _this->head;
1314 /****************************************************************************/
1315 Pk11Install_ListIter*
1316 Pk11Install_ListIter_new_default()
1318 Pk11Install_ListIter* new_this;
1319 new_this = (Pk11Install_ListIter*)
1320 PR_Malloc(sizeof(Pk11Install_ListIter));
1321 Pk11Install_ListIter_init(new_this);
1325 /****************************************************************************/
1327 Pk11Install_ListIter_init(Pk11Install_ListIter* _this)
1330 _this->current = NULL;
1333 /****************************************************************************/
1334 Pk11Install_ListIter*
1335 Pk11Install_ListIter_new(const Pk11Install_ValueList *_list)
1337 Pk11Install_ListIter* new_this;
1338 new_this = (Pk11Install_ListIter*)
1339 PR_Malloc(sizeof(Pk11Install_ListIter));
1340 new_this->list = _list;
1341 new_this->current = _list->head;
1345 /****************************************************************************/
1347 Pk11Install_ListIter_delete(Pk11Install_ListIter* _this)
1350 _this->current=NULL;
1353 /****************************************************************************/
1355 Pk11Install_ListIter_reset(Pk11Install_ListIter* _this)
1358 _this->current = _this->list->head;
1362 /*************************************************************************/
1364 Pk11Install_ListIter_nextItem(Pk11Install_ListIter* _this)
1366 if(_this->current) {
1367 _this->current = _this->current->next;
1370 return _this->current;
1373 /****************************************************************************/
1374 Pk11Install_ValueList*
1375 Pk11Install_ValueList_new()
1377 Pk11Install_ValueList* new_this;
1378 new_this = (Pk11Install_ValueList*)
1379 PR_Malloc(sizeof(Pk11Install_ValueList));
1380 new_this->numItems = 0;
1381 new_this->numPairs = 0;
1382 new_this->numStrings = 0;
1383 new_this->head = NULL;
1387 /****************************************************************************/
1389 Pk11Install_ValueList_delete(Pk11Install_ValueList* _this)
1392 Pk11Install_Value *tmp;
1393 Pk11Install_Value *list;
1396 while(list != NULL) {
1404 /****************************************************************************/
1406 Pk11Install_Value_new_default()
1408 Pk11Install_Value* new_this;
1409 new_this = (Pk11Install_Value*)PR_Malloc(sizeof(Pk11Install_Value));
1410 new_this->type = STRING_VALUE;
1411 new_this->string = NULL;
1412 new_this->pair = NULL;
1413 new_this->next = NULL;
1417 /****************************************************************************/
1419 Pk11Install_Value_new(ValueType _type, Pk11Install_Pointer ptr)
1421 Pk11Install_Value* new_this;
1422 new_this = Pk11Install_Value_new_default();
1423 new_this->type = _type;
1424 if(_type == STRING_VALUE) {
1425 new_this->pair = NULL;
1426 new_this->string = ptr.string;
1428 new_this->string = NULL;
1429 new_this->pair = ptr.pair;
1434 /****************************************************************************/
1436 Pk11Install_Value_delete(Pk11Install_Value* _this)
1438 if(_this->type == STRING_VALUE) {
1439 PR_Free(_this->string);
1441 PR_Free(_this->pair);
1445 /****************************************************************************/
1447 Pk11Install_Pair_new_default()
1449 return Pk11Install_Pair_new(NULL,NULL);
1452 /****************************************************************************/
1454 Pk11Install_Pair_new(char *_key, Pk11Install_ValueList *_list)
1456 Pk11Install_Pair* new_this;
1457 new_this = (Pk11Install_Pair*)PR_Malloc(sizeof(Pk11Install_Pair));
1458 new_this->key = _key;
1459 new_this->list = _list;
1463 /****************************************************************************/
1465 Pk11Install_Pair_delete(Pk11Install_Pair* _this)
1467 PR_Free(_this->key);
1468 Pk11Install_ValueList_delete(_this->list);
1469 PR_Free(_this->list);
1472 /*************************************************************************/
1474 Pk11Install_Pair_Print(Pk11Install_Pair* _this, int pad)
1477 /*PAD(pad); printf("**Pair\n");
1478 PAD(pad); printf("***Key====\n");*/
1479 PAD(pad); printf("%s {\n", _this->key);
1480 /*PAD(pad); printf("====\n");*/
1481 /*PAD(pad); printf("***ValueList\n");*/
1482 Pk11Install_ValueList_Print(_this->list,pad+PADINC);
1483 PAD(pad); printf("}\n");
1487 /*************************************************************************/
1489 Pk11Install_ValueList_Print(Pk11Install_ValueList* _this, int pad)
1491 Pk11Install_Value *v;
1493 /*PAD(pad);printf("**Value List**\n");*/
1494 for(v = _this->head; v != NULL; v=v->next) {
1495 Pk11Install_Value_Print(v,pad);
1499 /*************************************************************************/
1501 Pk11Install_Value_Print(Pk11Install_Value* _this, int pad)
1503 /*PAD(pad); printf("**Value, type=%s\n",
1504 type==STRING_VALUE ? "string" : "pair");*/
1505 if(_this->type==STRING_VALUE) {
1506 /*PAD(pad+PADINC); printf("====\n");*/
1507 PAD(pad); printf("%s\n", _this->string);
1508 /*PAD(pad+PADINC); printf("====\n");*/
1510 Pk11Install_Pair_Print(_this->pair,pad+PADINC);