/security/nss/cmd/modutil/install-ds.c

http://github.com/zpao/v8monkey · C · 1544 lines · 1164 code · 126 blank · 254 comment · 223 complexity · 78219423cdb764e0b7fc0f3fb24226ae MD5 · raw file

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