1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "install-ds.h"
43 #define PORT_Strcasecmp PL_strcasecmp
45 #define MODULE_FILE_STRING "ModuleFile"
46 #define MODULE_NAME_STRING "ModuleName"
47 #define MECH_FLAGS_STRING "DefaultMechanismFlags"
48 #define CIPHER_FLAGS_STRING "DefaultCipherFlags"
49 #define FILES_STRING "Files"
50 #define FORWARD_COMPATIBLE_STRING "ForwardCompatible"
51 #define PLATFORMS_STRING "Platforms"
52 #define RELATIVE_DIR_STRING "RelativePath"
53 #define ABSOLUTE_DIR_STRING "AbsolutePath"
54 #define FILE_PERMISSIONS_STRING "FilePermissions"
55 #define EQUIVALENT_PLATFORM_STRING "EquivalentPlatform"
56 #define EXECUTABLE_STRING "Executable"
58 #define DEFAULT_PERMISSIONS 0777
60 #define PLATFORM_SEPARATOR_CHAR ':'
66 BOGUS_FILE_PERMISSIONS
,
69 EMPTY_PLATFORM_STRING
,
70 BOGUS_PLATFORM_STRING
,
91 /* Indexed by the above error codes */
92 static const char *errString
[] = {
93 "%s: Invalid relative directory",
94 "%s: Invalid absolute directory",
95 "%s: Invalid file permissions",
96 "%s: No relative directory specified",
97 "%s: No absolute directory specified",
98 "Empty string given for platform name",
99 "%s: invalid platform string",
100 "More than one ModuleFile entry given for platform %s",
101 "More than one ModuleName entry given for platform %s",
102 "Invalid ModuleFile specification for platform %s",
103 "Invalid ModuleName specification for platform %s",
104 "More than one DefaultMechanismFlags entry given for platform %s",
105 "Invalid DefaultMechanismFlags specification for platform %s",
106 "More than one DefaultCipherFlags entry given for platform %s",
107 "Invalid DefaultCipherFlags entry given for platform %s",
108 "More than one Files entry given for platform %s",
109 "More than one EquivalentPlatform entry given for platform %s",
110 "Invalid EquivalentPlatform specification for platform %s",
111 "Module %s uses an EquivalentPlatform but also specifies its own"
113 "No Files specification in module %s",
114 "No ModuleFile specification in module %s",
115 "No ModuleName specification in module %s",
116 "No Platforms specification in installer script",
117 "Platform %s has an equivalency loop",
118 "Module file \"%s\" in platform \"%s\" does not exist"
121 static char* PR_Strdup(const char* str
);
123 #define PAD(x) {int i; for(i=0;i<x;i++) printf(" ");}
127 Pk11Install_File_new()
129 Pk11Install_File
* new_this
;
130 new_this
= (Pk11Install_File
*)PR_Malloc(sizeof(Pk11Install_File
));
131 Pk11Install_File_init(new_this
);
136 Pk11Install_File_init(Pk11Install_File
* _this
)
139 _this
->relativePath
=NULL
;
140 _this
->absolutePath
=NULL
;
141 _this
->executable
=PR_FALSE
;
142 _this
->permissions
=0;
146 //////////////////////////////////////////////////////////////////////////
147 // Method: ~Pk11Install_File
148 // Class: Pk11Install_File
149 // Notes: Destructor.
152 Pk11Install_File_delete(Pk11Install_File
* _this
)
154 Pk11Install_File_Cleanup(_this
);
158 //////////////////////////////////////////////////////////////////////////
160 // Class: Pk11Install_File
163 Pk11Install_File_Cleanup(Pk11Install_File
* _this
)
166 PR_Free(_this
->jarPath
);
167 _this
->jarPath
= NULL
;
169 if(_this
->relativePath
) {
170 PR_Free(_this
->relativePath
);
171 _this
->relativePath
= NULL
;
173 if(_this
->absolutePath
) {
174 PR_Free(_this
->absolutePath
);
175 _this
->absolutePath
= NULL
;
178 _this
->permissions
= 0;
179 _this
->executable
= PR_FALSE
;
183 //////////////////////////////////////////////////////////////////////////
185 // Class: Pk11Install_File
186 // Notes: Creates a file data structure from a syntax tree.
187 // Returns: NULL for success, otherwise an error message.
190 Pk11Install_File_Generate(Pk11Install_File
* _this
,
191 const Pk11Install_Pair
*pair
)
193 Pk11Install_ListIter
*iter
;
194 Pk11Install_Value
*val
;
195 Pk11Install_Pair
*subpair
;
196 Pk11Install_ListIter
*subiter
;
197 Pk11Install_Value
*subval
;
207 /* Clear out old values */
208 Pk11Install_File_Cleanup(_this
);
210 _this
->jarPath
= PR_Strdup(pair
->key
);
212 /* Go through all the pairs under this file heading */
213 iter
= Pk11Install_ListIter_new(pair
->list
);
214 for( ; (val
= iter
->current
); Pk11Install_ListIter_nextItem(iter
)) {
215 if(val
->type
== PAIR_VALUE
) {
218 /* Relative directory */
219 if(!PORT_Strcasecmp(subpair
->key
, RELATIVE_DIR_STRING
)) {
220 subiter
= Pk11Install_ListIter_new(subpair
->list
);
221 subval
= subiter
->current
;
222 if(!subval
|| (subval
->type
!= STRING_VALUE
)){
223 errStr
= PR_smprintf(errString
[BOGUS_RELATIVE_DIR
],
227 _this
->relativePath
= PR_Strdup(subval
->string
);
228 Pk11Install_ListIter_delete(subiter
);
231 /* Absolute directory */
232 } else if( !PORT_Strcasecmp(subpair
->key
, ABSOLUTE_DIR_STRING
)) {
233 subiter
= Pk11Install_ListIter_new(subpair
->list
);
234 subval
= subiter
->current
;
235 if(!subval
|| (subval
->type
!= STRING_VALUE
)){
236 errStr
= PR_smprintf(errString
[BOGUS_ABSOLUTE_DIR
],
240 _this
->absolutePath
= PR_Strdup(subval
->string
);
241 Pk11Install_ListIter_delete(subiter
);
244 /* file permissions */
245 } else if( !PORT_Strcasecmp(subpair
->key
,
246 FILE_PERMISSIONS_STRING
)) {
247 subiter
= Pk11Install_ListIter_new(subpair
->list
);
248 subval
= subiter
->current
;
249 if(!subval
|| (subval
->type
!= STRING_VALUE
)){
250 errStr
= PR_smprintf(errString
[BOGUS_FILE_PERMISSIONS
],
254 _this
->permissions
= (int) strtol(subval
->string
, &endp
, 8);
255 if(*endp
!= '\0' || subval
->string
== "\0") {
256 errStr
= PR_smprintf(errString
[BOGUS_FILE_PERMISSIONS
],
261 Pk11Install_ListIter_delete(subiter
);
265 if(!PORT_Strcasecmp(val
->string
, EXECUTABLE_STRING
)) {
266 _this
->executable
= PR_TRUE
;
271 /* Default permission value */
273 _this
->permissions
= DEFAULT_PERMISSIONS
;
276 /* Make sure we got all the information */
277 if(!_this
->relativePath
&& !_this
->absolutePath
) {
278 errStr
= PR_smprintf(errString
[NO_ABSOLUTE_DIR
], _this
->jarPath
);
282 if(!_this
->relativePath
) {
283 errStr
= PR_smprintf(errString
[NO_RELATIVE_DIR
], _this
->jarPath
);
286 if(!_this
->absolutePath
) {
287 errStr
= PR_smprintf(errString
[NO_ABSOLUTE_DIR
], _this
->jarPath
);
294 Pk11Install_ListIter_delete(iter
);
298 Pk11Install_ListIter_delete(subiter
);
305 //////////////////////////////////////////////////////////////////////////
307 // Class: Pk11Install_File
310 Pk11Install_File_Print(Pk11Install_File
* _this
, int pad
)
312 PAD(pad
); printf("jarPath: %s\n",
313 _this
->jarPath
? _this
->jarPath
: "<NULL>");
314 PAD(pad
); printf("relativePath: %s\n",
315 _this
->relativePath
? _this
->relativePath
: "<NULL>");
316 PAD(pad
); printf("absolutePath: %s\n",
317 _this
->absolutePath
? _this
->absolutePath
: "<NULL>");
318 PAD(pad
); printf("permissions: %o\n", _this
->permissions
);
321 Pk11Install_PlatformName
*
322 Pk11Install_PlatformName_new()
324 Pk11Install_PlatformName
* new_this
;
325 new_this
= (Pk11Install_PlatformName
*)
326 PR_Malloc(sizeof(Pk11Install_PlatformName
));
327 Pk11Install_PlatformName_init(new_this
);
332 Pk11Install_PlatformName_init(Pk11Install_PlatformName
* _this
)
335 _this
->verString
= NULL
;
336 _this
->numDigits
= 0;
341 //////////////////////////////////////////////////////////////////////////
342 // Method: ~Pk11Install_PlatformName
343 // Class: Pk11Install_PlatformName
346 Pk11Install_PlatformName_delete(Pk11Install_PlatformName
* _this
)
348 Pk11Install_PlatformName_Cleanup(_this
);
352 //////////////////////////////////////////////////////////////////////////
354 // Class: Pk11Install_PlatformName
357 Pk11Install_PlatformName_Cleanup(Pk11Install_PlatformName
* _this
)
363 if(_this
->verString
) {
365 for (i
=0; i
<_this
->numDigits
; i
++) {
366 PR_Free(_this
->verString
[i
]);
368 PR_Free(_this
->verString
);
369 _this
->verString
= NULL
;
372 PR_Free(_this
->arch
);
375 _this
->numDigits
= 0;
379 //////////////////////////////////////////////////////////////////////////
381 // Class: Pk11Install_PlatformName
382 // Notes: Extracts the information from a platform string.
385 Pk11Install_PlatformName_Generate(Pk11Install_PlatformName
* _this
,
390 char *end
, *start
; /* start and end of a section (OS, version, arch)*/
391 char *pend
, *pstart
; /* start and end of one portion of version*/
392 char *endp
; /* used by strtol*/
399 errStr
= PR_smprintf(errString
[EMPTY_PLATFORM_STRING
]);
402 copy
= PR_Strdup(str
);
407 end
= strchr(copy
, PLATFORM_SEPARATOR_CHAR
);
408 if(!end
|| end
==copy
) {
409 errStr
= PR_smprintf(errString
[BOGUS_PLATFORM_STRING
], str
);
414 _this
->OS
= PR_Strdup(copy
);
417 // Get the digits of the version of form: x.x.x (arbitrary number of digits)
421 end
= strchr(start
, PLATFORM_SEPARATOR_CHAR
);
423 errStr
= PR_smprintf(errString
[BOGUS_PLATFORM_STRING
], str
);
429 /* Find out how many periods*/
432 while( (pend
=strchr(pstart
, '.')) ) {
436 _this
->numDigits
= 1+ periods
;
437 _this
->verString
= (char**)PR_Malloc(sizeof(char*)*_this
->numDigits
);
441 /* Get the digits before each period*/
442 while( (pend
=strchr(pstart
, '.')) ) {
444 errStr
= PR_smprintf(errString
[BOGUS_PLATFORM_STRING
], str
);
448 _this
->verString
[i
] = PR_Strdup(pstart
);
450 if(endp
==pstart
|| (*endp
!= '\0')) {
451 errStr
= PR_smprintf(errString
[BOGUS_PLATFORM_STRING
], str
);
457 /* Last digit comes after the last period*/
458 if(*pstart
== '\0') {
459 errStr
= PR_smprintf(errString
[BOGUS_PLATFORM_STRING
], str
);
462 _this
->verString
[i
] = PR_Strdup(pstart
);
464 if(endp==pstart || (*endp != '\0')) {
465 errStr = PR_smprintf(errString[BOGUS_PLATFORM_STRING], str);
470 _this
->verString
= NULL
;
471 _this
->numDigits
= 0;
475 // Get the architecture
478 if( strchr(start
, PLATFORM_SEPARATOR_CHAR
) ) {
479 errStr
= PR_smprintf(errString
[BOGUS_PLATFORM_STRING
], str
);
482 _this
->arch
= PR_Strdup(start
);
493 if(_this
->verString
) {
494 for (i
=0; i
<_this
->numDigits
; i
++) {
495 PR_Free(_this
->verString
[i
]);
497 PR_Free(_this
->verString
);
498 _this
->verString
= NULL
;
500 _this
->numDigits
= 0;
502 PR_Free(_this
->arch
);
510 //////////////////////////////////////////////////////////////////////////
511 // Method: operator ==
512 // Class: Pk11Install_PlatformName
513 // Returns: PR_TRUE if the platform have the same OS, arch, and version
516 Pk11Install_PlatformName_equal(Pk11Install_PlatformName
* _this
,
517 Pk11Install_PlatformName
* cmp
)
521 if(!_this
->OS
|| !_this
->arch
|| !cmp
->OS
|| !cmp
->arch
) {
525 if( PORT_Strcasecmp(_this
->OS
, cmp
->OS
) ||
526 PORT_Strcasecmp(_this
->arch
, cmp
->arch
) ||
527 _this
->numDigits
!= cmp
->numDigits
) {
531 for(i
=0; i
< _this
->numDigits
; i
++) {
532 if(PORT_Strcasecmp(_this
->verString
[i
], cmp
->verString
[i
])) {
540 //////////////////////////////////////////////////////////////////////////
541 // Method: operator <=
542 // Class: Pk11Install_PlatformName
543 // Returns: PR_TRUE if the platform have the same OS and arch and a lower
547 Pk11Install_PlatformName_lteq(Pk11Install_PlatformName
* _this
,
548 Pk11Install_PlatformName
* cmp
)
550 return (Pk11Install_PlatformName_equal(_this
,cmp
) ||
551 Pk11Install_PlatformName_lt(_this
,cmp
)) ? PR_TRUE
: PR_FALSE
;
555 //////////////////////////////////////////////////////////////////////////
556 // Method: operator <
557 // Class: Pk11Install_PlatformName
558 // Returns: PR_TRUE if the platform have the same OS and arch and a greater
562 Pk11Install_PlatformName_lt(Pk11Install_PlatformName
* _this
,
563 Pk11Install_PlatformName
* cmp
)
567 if(!_this
->OS
|| !_this
->arch
|| !cmp
->OS
|| !cmp
->arch
) {
571 if( PORT_Strcasecmp(_this
->OS
, cmp
->OS
) ) {
574 if( PORT_Strcasecmp(_this
->arch
, cmp
->arch
) ) {
578 for(i
=0; (i
< _this
->numDigits
) && (i
< cmp
->numDigits
); i
++) {
579 scmp
= PORT_Strcasecmp(_this
->verString
[i
], cmp
->verString
[i
]);
582 } else if (scmp
< 0) {
586 /* All the digits they have in common are the same. */
587 if(_this
->numDigits
< cmp
->numDigits
) {
595 //////////////////////////////////////////////////////////////////////////
597 // Class: Pk11Install_PlatformName
598 // Returns: String composed of OS, release, and architecture separated
599 // by the separator char. Memory is allocated by this function
600 // but is the responsibility of the caller to de-allocate.
603 Pk11Install_PlatformName_GetString(Pk11Install_PlatformName
* _this
)
613 OS_
= _this
->OS
? _this
->OS
: "";
614 arch_
= _this
->arch
? _this
->arch
: "";
616 ver
= Pk11Install_PlatformName_GetVerString(_this
);
617 ret
= PR_smprintf("%s%c%s%c%s", OS_
, PLATFORM_SEPARATOR_CHAR
, ver
,
618 PLATFORM_SEPARATOR_CHAR
, arch_
);
626 //////////////////////////////////////////////////////////////////////////
627 // Method: GetVerString
628 // Class: Pk11Install_PlatformName
629 // Returns: The version string for this platform, in the form x.x.x with an
630 // arbitrary number of digits. Memory allocated by function,
631 // must be de-allocated by caller.
634 Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName
* _this
)
641 tmp
= (char*)PR_Malloc(80*_this
->numDigits
+1);
644 for(i
=0; i
< _this
->numDigits
-1; i
++) {
645 sprintf(buf
, "%s.", _this
->verString
[i
]);
648 if(i
< _this
->numDigits
) {
649 sprintf(buf
, "%s", _this
->verString
[i
]);
653 ret
= PR_Strdup(tmp
);
660 //////////////////////////////////////////////////////////////////////////
662 // Class: Pk11Install_PlatformName
665 Pk11Install_PlatformName_Print(Pk11Install_PlatformName
* _this
, int pad
)
667 PAD(pad
); printf("OS: %s\n", _this
->OS
? _this
->OS
: "<NULL>");
668 PAD(pad
); printf("Digits: ");
669 if(_this
->numDigits
== 0) {
672 printf("%s\n", Pk11Install_PlatformName_GetVerString(_this
));
674 PAD(pad
); printf("arch: %s\n", _this
->arch
? _this
->arch
: "<NULL>");
677 Pk11Install_Platform
*
678 Pk11Install_Platform_new()
680 Pk11Install_Platform
* new_this
;
681 new_this
= (Pk11Install_Platform
*)PR_Malloc(sizeof(Pk11Install_Platform
));
682 Pk11Install_Platform_init(new_this
);
687 Pk11Install_Platform_init(Pk11Install_Platform
* _this
)
689 Pk11Install_PlatformName_init(&_this
->name
);
690 Pk11Install_PlatformName_init(&_this
->equivName
);
692 _this
->usesEquiv
= PR_FALSE
;
693 _this
->moduleFile
= NULL
;
694 _this
->moduleName
= NULL
;
696 _this
->mechFlags
= 0;
697 _this
->cipherFlags
= 0;
703 //////////////////////////////////////////////////////////////////////////
704 // Method: ~Pk11Install_Platform
705 // Class: Pk11Install_Platform
708 Pk11Install_Platform_delete(Pk11Install_Platform
* _this
)
710 Pk11Install_Platform_Cleanup(_this
);
714 //////////////////////////////////////////////////////////////////////////
716 // Class: Pk11Install_Platform
719 Pk11Install_Platform_Cleanup(Pk11Install_Platform
* _this
)
722 if(_this
->moduleFile
) {
723 PR_Free(_this
->moduleFile
);
724 _this
->moduleFile
= NULL
;
726 if(_this
->moduleName
) {
727 PR_Free(_this
->moduleName
);
728 _this
->moduleName
= NULL
;
731 for (i
=0;i
<_this
->numFiles
;i
++) {
732 Pk11Install_File_delete(&_this
->files
[i
]);
734 PR_Free(_this
->files
);
738 _this
->usesEquiv
= PR_FALSE
;
741 _this
->mechFlags
= _this
->cipherFlags
= 0;
745 //////////////////////////////////////////////////////////////////////////
747 // Class: Pk11Install_Platform
748 // Notes: Creates a platform data structure from a syntax tree.
749 // Returns: NULL for success, otherwise an error message.
752 Pk11Install_Platform_Generate(Pk11Install_Platform
* _this
,
753 const Pk11Install_Pair
*pair
)
759 Pk11Install_ListIter
*iter
;
760 Pk11Install_Value
*val
;
761 Pk11Install_Value
*subval
;
762 Pk11Install_Pair
*subpair
;
763 Pk11Install_ListIter
*subiter
;
764 PRBool gotModuleFile
, gotModuleName
, gotMech
,
765 gotCipher
, gotFiles
, gotEquiv
;
771 gotModuleFile
=gotModuleName
=gotMech
=gotCipher
=gotFiles
=gotEquiv
=PR_FALSE
;
772 Pk11Install_Platform_Cleanup(_this
);
774 errStr
= Pk11Install_PlatformName_Generate(&_this
->name
,pair
->key
);
776 tmp
= PR_smprintf("%s: %s", pair
->key
, errStr
);
777 PR_smprintf_free(errStr
);
782 iter
= Pk11Install_ListIter_new(pair
->list
);
783 for( ; (val
=iter
->current
); Pk11Install_ListIter_nextItem(iter
)) {
784 if(val
->type
==PAIR_VALUE
) {
787 if( !PORT_Strcasecmp(subpair
->key
, MODULE_FILE_STRING
)) {
789 errStr
= PR_smprintf(errString
[REPEAT_MODULE_FILE
],
790 Pk11Install_PlatformName_GetString(&_this
->name
));
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_FILE
],
797 Pk11Install_PlatformName_GetString(&_this
->name
));
800 _this
->moduleFile
= PR_Strdup(subval
->string
);
801 Pk11Install_ListIter_delete(subiter
);
804 gotModuleFile
= PR_TRUE
;
805 } else if(!PORT_Strcasecmp(subpair
->key
, MODULE_NAME_STRING
)){
807 errStr
= PR_smprintf(errString
[REPEAT_MODULE_NAME
],
808 Pk11Install_PlatformName_GetString(&_this
->name
));
811 subiter
= Pk11Install_ListIter_new(subpair
->list
);
812 subval
= subiter
->current
;
813 if(!subval
|| (subval
->type
!= STRING_VALUE
)) {
814 errStr
= PR_smprintf(errString
[BOGUS_MODULE_NAME
],
815 Pk11Install_PlatformName_GetString(&_this
->name
));
818 _this
->moduleName
= PR_Strdup(subval
->string
);
819 Pk11Install_ListIter_delete(subiter
);
822 gotModuleName
= PR_TRUE
;
823 } else if(!PORT_Strcasecmp(subpair
->key
, MECH_FLAGS_STRING
)) {
827 errStr
= PR_smprintf(errString
[REPEAT_MECH
],
828 Pk11Install_PlatformName_GetString(&_this
->name
));
831 subiter
= Pk11Install_ListIter_new(subpair
->list
);
832 subval
= subiter
->current
;
833 if(!subval
|| (subval
->type
!= STRING_VALUE
)) {
834 errStr
= PR_smprintf(errString
[BOGUS_MECH_FLAGS
],
835 Pk11Install_PlatformName_GetString(&_this
->name
));
838 _this
->mechFlags
= strtol(subval
->string
, &endptr
, 0);
839 if(*endptr
!='\0' || (endptr
==subval
->string
) ) {
840 errStr
= PR_smprintf(errString
[BOGUS_MECH_FLAGS
],
841 Pk11Install_PlatformName_GetString(&_this
->name
));
844 Pk11Install_ListIter_delete(subiter
);
848 } else if(!PORT_Strcasecmp(subpair
->key
,CIPHER_FLAGS_STRING
)) {
852 errStr
= PR_smprintf(errString
[REPEAT_CIPHER
],
853 Pk11Install_PlatformName_GetString(&_this
->name
));
856 subiter
= Pk11Install_ListIter_new(subpair
->list
);
857 subval
= subiter
->current
;
858 if(!subval
|| (subval
->type
!= STRING_VALUE
)) {
859 errStr
= PR_smprintf(errString
[BOGUS_CIPHER_FLAGS
],
860 Pk11Install_PlatformName_GetString(&_this
->name
));
863 _this
->cipherFlags
= strtol(subval
->string
, &endptr
, 0);
864 if(*endptr
!='\0' || (endptr
==subval
->string
) ) {
865 errStr
= PR_smprintf(errString
[BOGUS_CIPHER_FLAGS
],
866 Pk11Install_PlatformName_GetString(&_this
->name
));
869 Pk11Install_ListIter_delete(subiter
);
873 } else if(!PORT_Strcasecmp(subpair
->key
, FILES_STRING
)) {
875 errStr
= PR_smprintf(errString
[REPEAT_FILES
],
876 Pk11Install_PlatformName_GetString(&_this
->name
));
879 subiter
= Pk11Install_ListIter_new(subpair
->list
);
880 _this
->numFiles
= subpair
->list
->numPairs
;
881 _this
->files
= (Pk11Install_File
*)
882 PR_Malloc(sizeof(Pk11Install_File
)*_this
->numFiles
);
883 for(i
=0; i
< _this
->numFiles
; i
++,
884 Pk11Install_ListIter_nextItem(subiter
)) {
885 Pk11Install_File_init(&_this
->files
[i
]);
886 val
= subiter
->current
;
887 if(val
&& (val
->type
==PAIR_VALUE
)) {
888 errStr
= Pk11Install_File_Generate(&_this
->files
[i
],val
->pair
);
890 tmp
= PR_smprintf("%s: %s",
891 Pk11Install_PlatformName_GetString(&_this
->name
),errStr
);
892 PR_smprintf_free(errStr
);
899 } else if(!PORT_Strcasecmp(subpair
->key
,
900 EQUIVALENT_PLATFORM_STRING
)) {
902 errStr
= PR_smprintf(errString
[REPEAT_EQUIV
],
903 Pk11Install_PlatformName_GetString(&_this
->name
));
906 subiter
= Pk11Install_ListIter_new(subpair
->list
);
907 subval
= subiter
->current
;
908 if(!subval
|| (subval
->type
!= STRING_VALUE
) ) {
909 errStr
= PR_smprintf(errString
[BOGUS_EQUIV
],
910 Pk11Install_PlatformName_GetString(&_this
->name
));
913 errStr
= Pk11Install_PlatformName_Generate(&_this
->equivName
,
916 tmp
= PR_smprintf("%s: %s",
917 Pk11Install_PlatformName_GetString(&_this
->name
), errStr
);
918 tmp
= PR_smprintf("%s: %s",
919 Pk11Install_PlatformName_GetString(&_this
->name
), errStr
);
920 PR_smprintf_free(errStr
);
924 _this
->usesEquiv
= PR_TRUE
;
929 /* Make sure we either have an EquivalentPlatform or all the other info */
930 if(_this
->usesEquiv
&&
931 (gotFiles
|| gotModuleFile
|| gotModuleName
|| gotMech
|| gotCipher
)) {
932 errStr
= PR_smprintf(errString
[EQUIV_TOO_MUCH_INFO
],
933 Pk11Install_PlatformName_GetString(&_this
->name
));
936 if(!gotFiles
&& !_this
->usesEquiv
) {
937 errStr
= PR_smprintf(errString
[NO_FILES
],
938 Pk11Install_PlatformName_GetString(&_this
->name
));
941 if(!gotModuleFile
&& !_this
->usesEquiv
) {
942 errStr
= PR_smprintf(errString
[NO_MODULE_FILE
],
943 Pk11Install_PlatformName_GetString(&_this
->name
));
946 if(!gotModuleName
&& !_this
->usesEquiv
) {
947 errStr
= PR_smprintf(errString
[NO_MODULE_NAME
],
948 Pk11Install_PlatformName_GetString(&_this
->name
));
952 /* Point the modFile pointer to the correct file */
954 for(i
=0; i
< _this
->numFiles
; i
++) {
955 if(!PORT_Strcasecmp(_this
->moduleFile
, _this
->files
[i
].jarPath
) ) {
960 if(_this
->modFile
==-1) {
961 errStr
= PR_smprintf(errString
[UNKNOWN_MODULE_FILE
],
963 Pk11Install_PlatformName_GetString(&_this
->name
));
979 //////////////////////////////////////////////////////////////////////////
981 // Class: Pk11Install_Platform
984 Pk11Install_Platform_Print(Pk11Install_Platform
* _this
, int pad
)
988 PAD(pad
); printf("Name:\n");
989 Pk11Install_PlatformName_Print(&_this
->name
,pad
+PADINC
);
990 PAD(pad
); printf("equivName:\n");
991 Pk11Install_PlatformName_Print(&_this
->equivName
,pad
+PADINC
);
993 if(_this
->usesEquiv
) {
994 printf("Uses equiv, which points to:\n");
995 Pk11Install_Platform_Print(_this
->equiv
,pad
+PADINC
);
997 printf("Doesn't use equiv\n");
1000 printf("Module File: %s\n", _this
->moduleFile
? _this
->moduleFile
1002 PAD(pad
); printf("mechFlags: %lx\n", _this
->mechFlags
);
1003 PAD(pad
); printf("cipherFlags: %lx\n", _this
->cipherFlags
);
1004 PAD(pad
); printf("Files:\n");
1005 for(i
=0; i
< _this
->numFiles
; i
++) {
1006 Pk11Install_File_Print(&_this
->files
[i
],pad
+PADINC
);
1007 PAD(pad
); printf("--------------------\n");
1012 //////////////////////////////////////////////////////////////////////////
1013 // Method: Pk11Install_Info
1014 // Class: Pk11Install_Info
1017 Pk11Install_Info_new()
1019 Pk11Install_Info
* new_this
;
1020 new_this
= (Pk11Install_Info
*)PR_Malloc(sizeof(Pk11Install_Info
));
1021 Pk11Install_Info_init(new_this
);
1026 Pk11Install_Info_init(Pk11Install_Info
* _this
)
1028 _this
->platforms
= NULL
;
1029 _this
->numPlatforms
= 0;
1030 _this
->forwardCompatible
= NULL
;
1031 _this
->numForwardCompatible
= 0;
1035 //////////////////////////////////////////////////////////////////////////
1036 // Method: ~Pk11Install_Info
1037 // Class: Pk11Install_Info
1040 Pk11Install_Info_delete(Pk11Install_Info
* _this
)
1042 Pk11Install_Info_Cleanup(_this
);
1046 //////////////////////////////////////////////////////////////////////////
1048 // Class: Pk11Install_Info
1051 Pk11Install_Info_Cleanup(Pk11Install_Info
* _this
)
1054 if(_this
->platforms
) {
1055 for (i
=0;i
<_this
->numPlatforms
;i
++) {
1056 Pk11Install_Platform_delete(&_this
->platforms
[i
]);
1058 PR_Free(&_this
->platforms
);
1059 _this
->platforms
= NULL
;
1060 _this
->numPlatforms
= 0;
1063 if(_this
->forwardCompatible
) {
1064 for (i
=0;i
<_this
->numForwardCompatible
;i
++) {
1065 Pk11Install_PlatformName_delete(&_this
->forwardCompatible
[i
]);
1067 PR_Free(&_this
->forwardCompatible
);
1068 _this
->numForwardCompatible
= 0;
1073 //////////////////////////////////////////////////////////////////////////
1075 // Class: Pk11Install_Info
1076 // Takes: Pk11Install_ValueList *list, the top-level list
1077 // resulting from parsing an installer file.
1078 // Returns: char*, NULL if successful, otherwise an error string.
1079 // Caller is responsible for freeing memory.
1082 Pk11Install_Info_Generate(Pk11Install_Info
* _this
,
1083 const Pk11Install_ValueList
*list
)
1086 Pk11Install_ListIter
*iter
;
1087 Pk11Install_Value
*val
;
1088 Pk11Install_Pair
*pair
;
1089 Pk11Install_ListIter
*subiter
;
1090 Pk11Install_Value
*subval
;
1091 Pk11Install_Platform
*first
, *second
;
1096 Pk11Install_Info_Cleanup(_this
);
1098 iter
= Pk11Install_ListIter_new(list
);
1099 for( ; (val
=iter
->current
); Pk11Install_ListIter_nextItem(iter
)) {
1100 if(val
->type
== PAIR_VALUE
) {
1103 if(!PORT_Strcasecmp(pair
->key
, FORWARD_COMPATIBLE_STRING
)) {
1104 subiter
= Pk11Install_ListIter_new(pair
->list
);
1105 _this
->numForwardCompatible
= pair
->list
->numStrings
;
1106 _this
->forwardCompatible
= (Pk11Install_PlatformName
*)
1107 PR_Malloc(sizeof(Pk11Install_PlatformName
)*
1108 _this
->numForwardCompatible
);
1109 for(i
=0; i
< _this
->numForwardCompatible
; i
++,
1110 Pk11Install_ListIter_nextItem(subiter
)) {
1111 subval
= subiter
->current
;
1112 if(subval
->type
== STRING_VALUE
) {
1113 errStr
= Pk11Install_PlatformName_Generate(
1114 &_this
->forwardCompatible
[i
], subval
->string
);
1120 Pk11Install_ListIter_delete(subiter
);
1123 } else if(!PORT_Strcasecmp(pair
->key
, PLATFORMS_STRING
)) {
1124 subiter
= Pk11Install_ListIter_new(pair
->list
);
1125 _this
->numPlatforms
= pair
->list
->numPairs
;
1126 _this
->platforms
= (Pk11Install_Platform
*)
1127 PR_Malloc(sizeof(Pk11Install_Platform
)*
1128 _this
->numPlatforms
);
1129 for(i
=0; i
< _this
->numPlatforms
; i
++,
1130 Pk11Install_ListIter_nextItem(subiter
)) {
1131 Pk11Install_Platform_init(&_this
->platforms
[i
]);
1132 subval
= subiter
->current
;
1133 if(subval
->type
== PAIR_VALUE
) {
1134 errStr
= Pk11Install_Platform_Generate(&_this
->platforms
[i
],subval
->pair
);
1140 Pk11Install_ListIter_delete(subiter
);
1147 if(_this
->numPlatforms
== 0) {
1148 errStr
= PR_smprintf(errString
[NO_PLATFORMS
]);
1154 // Now process equivalent platforms
1157 // First the naive pass
1159 for(i
=0; i
< _this
->numPlatforms
; i
++) {
1160 if(_this
->platforms
[i
].usesEquiv
) {
1161 _this
->platforms
[i
].equiv
= NULL
;
1162 for(j
=0; j
< _this
->numPlatforms
; j
++) {
1163 if (Pk11Install_PlatformName_equal(&_this
->platforms
[i
].equivName
,
1164 &_this
->platforms
[j
].name
)) {
1166 errStr
= PR_smprintf(errString
[EQUIV_LOOP
],
1167 Pk11Install_PlatformName_GetString(&_this
->platforms
[i
].name
));
1170 _this
->platforms
[i
].equiv
= &_this
->platforms
[j
];
1174 if(_this
->platforms
[i
].equiv
== NULL
) {
1175 errStr
= PR_smprintf(errString
[BOGUS_EQUIV
],
1176 Pk11Install_PlatformName_GetString(&_this
->platforms
[i
].name
));
1183 // Now the intelligent pass, which will also detect loops.
1184 // We will send two pointers through the linked list of equivalent
1185 // platforms. Both start with the current node. "first" traverses
1186 // two nodes for each iteration. "second" lags behind, only traversing
1187 // one node per iteration. Eventually one of two things will happen:
1188 // first will hit the end of the list (a platform that doesn't use
1189 // an equivalency), or first will equal second if there is a loop.
1191 for(i
=0; i
< _this
->numPlatforms
; i
++) {
1192 if(_this
->platforms
[i
].usesEquiv
) {
1193 second
= _this
->platforms
[i
].equiv
;
1194 if(!second
->usesEquiv
) {
1195 /* The first link is the terminal node */
1198 first
= second
->equiv
;
1199 while(first
->usesEquiv
) {
1200 if(first
== second
) {
1201 errStr
= PR_smprintf(errString
[EQUIV_LOOP
],
1202 Pk11Install_PlatformName_GetString(&_this
->platforms
[i
].name
));
1205 first
= first
->equiv
;
1206 if(!first
->usesEquiv
) {
1209 if(first
== second
) {
1210 errStr
= PR_smprintf(errString
[EQUIV_LOOP
],
1211 Pk11Install_PlatformName_GetString(&_this
->platforms
[i
].name
));
1214 second
= second
->equiv
;
1215 first
= first
->equiv
;
1217 _this
->platforms
[i
].equiv
= first
;
1223 Pk11Install_ListIter_delete(iter
);
1228 Pk11Install_ListIter_delete(subiter
);
1236 //////////////////////////////////////////////////////////////////////////
1237 // Method: GetBestPlatform
1238 // Class: Pk11Install_Info
1239 // Takes: char *myPlatform, the platform we are currently running
1242 Pk11Install_Platform
*
1243 Pk11Install_Info_GetBestPlatform(Pk11Install_Info
* _this
, char *myPlatform
)
1245 Pk11Install_PlatformName plat
;
1251 Pk11Install_PlatformName_init(&plat
);
1252 if( (errStr
=Pk11Install_PlatformName_Generate(&plat
, myPlatform
)) ) {
1253 PR_smprintf_free(errStr
);
1257 /* First try real platforms */
1258 for(i
=0; i
< _this
->numPlatforms
; i
++) {
1259 if(Pk11Install_PlatformName_equal(&_this
->platforms
[i
].name
,&plat
)) {
1260 if(_this
->platforms
[i
].equiv
) {
1261 return _this
->platforms
[i
].equiv
;
1264 return &_this
->platforms
[i
];
1269 /* Now try forward compatible platforms */
1270 for(i
=0; i
< _this
->numForwardCompatible
; i
++) {
1271 if(Pk11Install_PlatformName_lteq(&_this
->forwardCompatible
[i
],&plat
)) {
1275 if(i
== _this
->numForwardCompatible
) {
1279 /* Got a forward compatible name, find the actual platform. */
1280 for(j
=0; j
< _this
->numPlatforms
; j
++) {
1281 if(Pk11Install_PlatformName_equal(&_this
->platforms
[j
].name
,
1282 &_this
->forwardCompatible
[i
])) {
1283 if(_this
->platforms
[j
].equiv
) {
1284 return _this
->platforms
[j
].equiv
;
1286 return &_this
->platforms
[j
];
1295 //////////////////////////////////////////////////////////////////////////
1297 // Class: Pk11Install_Info
1300 Pk11Install_Info_Print(Pk11Install_Info
* _this
, int pad
)
1304 PAD(pad
); printf("Forward Compatible:\n");
1305 for(i
= 0; i
< _this
->numForwardCompatible
; i
++) {
1306 Pk11Install_PlatformName_Print(&_this
->forwardCompatible
[i
],pad
+PADINC
);
1307 PAD(pad
); printf("-------------------\n");
1309 PAD(pad
); printf("Platforms:\n");
1310 for( i
= 0; i
< _this
->numPlatforms
; i
++) {
1311 Pk11Install_Platform_Print(&_this
->platforms
[i
],pad
+PADINC
);
1312 PAD(pad
); printf("-------------------\n");
1317 //////////////////////////////////////////////////////////////////////////
1320 PR_Strdup(const char* str
)
1323 tmp
= (char*) PR_Malloc((unsigned int)(strlen(str
)+1));
1328 /* The global value list, the top of the tree */
1329 Pk11Install_ValueList
* Pk11Install_valueList
=NULL
;
1331 /****************************************************************************/
1333 Pk11Install_ValueList_AddItem(Pk11Install_ValueList
* _this
,
1334 Pk11Install_Value
*item
)
1337 if (item
->type
== STRING_VALUE
) {
1338 _this
->numStrings
++;
1342 item
->next
= _this
->head
;
1346 /****************************************************************************/
1347 Pk11Install_ListIter
*
1348 Pk11Install_ListIter_new_default()
1350 Pk11Install_ListIter
* new_this
;
1351 new_this
= (Pk11Install_ListIter
*)
1352 PR_Malloc(sizeof(Pk11Install_ListIter
));
1353 Pk11Install_ListIter_init(new_this
);
1357 /****************************************************************************/
1359 Pk11Install_ListIter_init(Pk11Install_ListIter
* _this
)
1362 _this
->current
= NULL
;
1365 /****************************************************************************/
1366 Pk11Install_ListIter
*
1367 Pk11Install_ListIter_new(const Pk11Install_ValueList
*_list
)
1369 Pk11Install_ListIter
* new_this
;
1370 new_this
= (Pk11Install_ListIter
*)
1371 PR_Malloc(sizeof(Pk11Install_ListIter
));
1372 new_this
->list
= _list
;
1373 new_this
->current
= _list
->head
;
1377 /****************************************************************************/
1379 Pk11Install_ListIter_delete(Pk11Install_ListIter
* _this
)
1382 _this
->current
=NULL
;
1385 /****************************************************************************/
1387 Pk11Install_ListIter_reset(Pk11Install_ListIter
* _this
)
1390 _this
->current
= _this
->list
->head
;
1394 /*************************************************************************/
1396 Pk11Install_ListIter_nextItem(Pk11Install_ListIter
* _this
)
1398 if(_this
->current
) {
1399 _this
->current
= _this
->current
->next
;
1402 return _this
->current
;
1405 /****************************************************************************/
1406 Pk11Install_ValueList
*
1407 Pk11Install_ValueList_new()
1409 Pk11Install_ValueList
* new_this
;
1410 new_this
= (Pk11Install_ValueList
*)
1411 PR_Malloc(sizeof(Pk11Install_ValueList
));
1412 new_this
->numItems
= 0;
1413 new_this
->numPairs
= 0;
1414 new_this
->numStrings
= 0;
1415 new_this
->head
= NULL
;
1419 /****************************************************************************/
1421 Pk11Install_ValueList_delete(Pk11Install_ValueList
* _this
)
1424 Pk11Install_Value
*tmp
;
1425 Pk11Install_Value
*list
;
1428 while(list
!= NULL
) {
1436 /****************************************************************************/
1438 Pk11Install_Value_new_default()
1440 Pk11Install_Value
* new_this
;
1441 new_this
= (Pk11Install_Value
*)PR_Malloc(sizeof(Pk11Install_Value
));
1442 new_this
->type
= STRING_VALUE
;
1443 new_this
->string
= NULL
;
1444 new_this
->pair
= NULL
;
1445 new_this
->next
= NULL
;
1449 /****************************************************************************/
1451 Pk11Install_Value_new(ValueType _type
, Pk11Install_Pointer ptr
)
1453 Pk11Install_Value
* new_this
;
1454 new_this
= Pk11Install_Value_new_default();
1455 new_this
->type
= _type
;
1456 if(_type
== STRING_VALUE
) {
1457 new_this
->pair
= NULL
;
1458 new_this
->string
= ptr
.string
;
1460 new_this
->string
= NULL
;
1461 new_this
->pair
= ptr
.pair
;
1466 /****************************************************************************/
1468 Pk11Install_Value_delete(Pk11Install_Value
* _this
)
1470 if(_this
->type
== STRING_VALUE
) {
1471 PR_Free(_this
->string
);
1473 PR_Free(_this
->pair
);
1477 /****************************************************************************/
1479 Pk11Install_Pair_new_default()
1481 return Pk11Install_Pair_new(NULL
,NULL
);
1484 /****************************************************************************/
1486 Pk11Install_Pair_new(char *_key
, Pk11Install_ValueList
*_list
)
1488 Pk11Install_Pair
* new_this
;
1489 new_this
= (Pk11Install_Pair
*)PR_Malloc(sizeof(Pk11Install_Pair
));
1490 new_this
->key
= _key
;
1491 new_this
->list
= _list
;
1495 /****************************************************************************/
1497 Pk11Install_Pair_delete(Pk11Install_Pair
* _this
)
1499 PR_Free(_this
->key
);
1500 Pk11Install_ValueList_delete(_this
->list
);
1501 PR_Free(_this
->list
);
1504 /*************************************************************************/
1506 Pk11Install_Pair_Print(Pk11Install_Pair
* _this
, int pad
)
1509 /*PAD(pad); printf("**Pair\n");
1510 PAD(pad); printf("***Key====\n");*/
1511 PAD(pad
); printf("%s {\n", _this
->key
);
1512 /*PAD(pad); printf("====\n");*/
1513 /*PAD(pad); printf("***ValueList\n");*/
1514 Pk11Install_ValueList_Print(_this
->list
,pad
+PADINC
);
1515 PAD(pad
); printf("}\n");
1519 /*************************************************************************/
1521 Pk11Install_ValueList_Print(Pk11Install_ValueList
* _this
, int pad
)
1523 Pk11Install_Value
*v
;
1525 /*PAD(pad);printf("**Value List**\n");*/
1526 for(v
= _this
->head
; v
!= NULL
; v
=v
->next
) {
1527 Pk11Install_Value_Print(v
,pad
);
1531 /*************************************************************************/
1533 Pk11Install_Value_Print(Pk11Install_Value
* _this
, int pad
)
1535 /*PAD(pad); printf("**Value, type=%s\n",
1536 type==STRING_VALUE ? "string" : "pair");*/
1537 if(_this
->type
==STRING_VALUE
) {
1538 /*PAD(pad+PADINC); printf("====\n");*/
1539 PAD(pad
); printf("%s\n", _this
->string
);
1540 /*PAD(pad+PADINC); printf("====\n");*/
1542 Pk11Install_Pair_Print(_this
->pair
,pad
+PADINC
);