PageRenderTime 61ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/carrot-jdk6-jnlp-macosx/src/javaws/share/native/launcher.c

https://github.com/carrot-garden/carrot-jnlper
C | 1060 lines | 740 code | 121 blank | 199 comment | 314 complexity | 6d5df32b3c806d18508b2b4ee2c2a6b0 MD5 | raw file
  1. /*
  2. * @(#)launcher.c 1.182 10/03/24
  3. *
  4. * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
  5. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Java Web Start launcher
  9. * -----------------------
  10. *
  11. * Synopsis:
  12. *
  13. * Usage: javaws [run-options] <jnlp-file>
  14. * javaws [control-options]
  15. *
  16. * where run-options include:
  17. * -verbose display additional output
  18. * -offline run the application in offline mode
  19. * -system run the application from the system cache only
  20. * -Xnosplash run without showing a splash screen
  21. * -J<options> supply options to the vm
  22. * -wait start java process and wait for its exit
  23. * -online --- internal option ---
  24. * -localfile --- internal option ---
  25. * -docbase --- internal option ---
  26. *
  27. * control-options include:
  28. * -viewer show the cache viewer in the java control panel
  29. * -uninstall remove all applications from the cache
  30. * -uninstall <jnlp-file> remove the application from the cache
  31. * -import [import-options] <jnlp-file> import the application to the cache
  32. * -shortcut --- internal option ---
  33. * -association --- internal option ---
  34. * -Xclearcache --- internal option ---
  35. * javaws -splash <port> <image file> --- internal option ---
  36. * -quick --- internal option ---
  37. *
  38. * import-options include:
  39. * -silent import silently (with no user interface)
  40. * -system import application into the system cache
  41. * -codebase <url> retrieve resources from the given codebase
  42. * -shortcut install shortcuts as if user allowed prompt
  43. * -association install associations as if user allowed prompt
  44. * -timestamp <MM/dd/yy hh:mm a> --- internal option ---
  45. * -expiration <MM/dd/yy hh:mm a> --- internal option ---
  46. * -quiet --- internal option ---
  47. */
  48. #include "launcher.h"
  49. #include "configurationFile.h"
  50. /* Reads the filename to load from from the passed in file. It is the callers
  51. * responsibility to free the returned string. This will return NULL if
  52. * there is a problem determining the filename.
  53. */
  54. char *ReadFileNameFromFile(char *file) {
  55. char *contents ;
  56. int size = ReadFileToBuffer(file, &contents);
  57. if (contents != NULL) {
  58. char *ptr = contents;
  59. while (*ptr != '\r' && *ptr != '\n' && *ptr != '\0') {
  60. ptr++;
  61. }
  62. *ptr = '\0';
  63. }
  64. return contents;
  65. }
  66. /*
  67. * Splash Screen
  68. */
  69. static int SplashPort = -1;
  70. static int SplashPID = -1;
  71. int GetSplashPort() {
  72. return SplashPort;
  73. }
  74. char * ShowSplashScreen(char* splash) {
  75. int port; /* the port that splash process will callback on */
  76. SOCKET server; /* the socket that splash process will callback on */
  77. int ret = 0;
  78. /* Create a temporary socket on an ephemeral port.We'll pass this
  79. * port to the splash application (as a command line argument)
  80. * so that it can send us the ephemeral port it's going to use.
  81. */
  82. if ((server = sysCreateListenerSocket(&port)) == INVALID_SOCKET) {
  83. return getMsgString(MSG_LISTENER_FAILED);
  84. }
  85. /* Launch the splash screen application with the callback port and
  86. * splash screen jpeg file to use as it's arguments
  87. */
  88. {
  89. char str[MAXPATHLEN], *argv[8];
  90. char exe[MAXPATHLEN];
  91. sysStrNPrintF(exe, sizeof(exe), "%s%c%s", sysGetApplicationHome(),
  92. FILE_SEPARATOR, sysGetJavawsbin());
  93. sysStrNPrintF(str, sizeof(str), "%d", port);
  94. argv[0] = "JavaWSSplashScreen";
  95. argv[1] = "-splash";
  96. argv[2] = str;
  97. argv[3] = splash;
  98. argv[4] = NULL;
  99. ret = sysExec(SYS_EXEC_FORK, exe, argv);
  100. }
  101. /* Wait for the splash screen to connect and tell us what ephemeral
  102. * port it's listening on.
  103. */
  104. if (ret > 0 ) {
  105. SOCKADDR_IN iname = {0};
  106. int client, length = sizeof(iname);
  107. char data[6];
  108. if ((client = accept(server, (SOCKADDR *)&iname, &length)) ==
  109. INVALID_SOCKET) {
  110. return getMsgString(MSG_ACCEPT_FAILED);
  111. }
  112. if (recv(client, data, 6, 0) != 6) {
  113. return getMsgString(MSG_RECV_FAILED);
  114. }
  115. if ((SplashPort = atoi(data)) <= 0) {
  116. return getMsgString(MSG_INVALID_PORT);
  117. }
  118. sysCloseSocket(client);
  119. sysCloseSocket(server);
  120. } else {
  121. return getMsgString(MSG_BADMSG);
  122. }
  123. return NULL;
  124. }
  125. /*
  126. *
  127. * java_arg stuff
  128. *
  129. */
  130. #define MAX_COUNT 50 /* 50 seems to be more than enough */
  131. static char *java_args[MAX_COUNT + 1];
  132. static int java_arg_strlen = 0; /* strlen of concat .. */
  133. static int java_arg_count = 1; /* skip over executable path */
  134. static char *java_arg_auxargs = NULL;
  135. static char *java_arg_Filename = NULL;
  136. static char *java_arg_command = NULL;
  137. char *GetVMArgsOption(char *vmoptions) {
  138. char * option=NULL;
  139. int n;
  140. if ((vmoptions != NULL) && (strlen(vmoptions) < MAXPATHLEN)) {
  141. static char tmp[MAXPATHLEN + 16];
  142. if(sysGetQuotesWholePropertySpec()) {
  143. n=sysStrNPrintF(tmp, sizeof(tmp), "-Djnlpx.vmargs=%s", vmoptions);
  144. if(0<=n && n<sizeof(tmp)) {
  145. option=sysQuoteString(tmp);
  146. }
  147. } else {
  148. char *vmOptionsQ = sysQuoteString(vmoptions);
  149. n=sysStrNPrintF(tmp, sizeof(tmp), "-Djnlpx.vmargs=%s", vmOptionsQ);
  150. if(0<=n && n<sizeof(tmp)) {
  151. option=strdup(tmp);
  152. }
  153. free(vmOptionsQ);
  154. }
  155. }
  156. return option;
  157. }
  158. char *GetProfileOption(char *path) {
  159. if ((path != NULL) && (strlen(path) > 0) && (strlen(path) < MAXPATHLEN)) {
  160. static char tmp[MAXPATHLEN + 32];
  161. sysStrNPrintF(tmp, sizeof(tmp), "-Djavaplugin.user.profile=%s", path);
  162. return tmp;
  163. }
  164. return NULL;
  165. }
  166. char *GetStartTimeOption(int time) {
  167. if (time > 0) {
  168. static char tmp[MAXPATHLEN + 16];
  169. sysStrNPrintF(tmp, sizeof(tmp)-1, "-Djnlp.start.time=%d", time);
  170. return strdup(tmp);
  171. }
  172. return NULL;
  173. }
  174. char *GetPerfLogOption(char *perflog) {
  175. if (perflog != NULL) {
  176. static char tmp[MAXPATHLEN + 16];
  177. char * ptr = strstr(perflog, "=");
  178. sysStrNPrintF(tmp, sizeof(tmp)-1, "-Dsun.perflog%s", (ptr == NULL ? "=NULL" : ptr));
  179. return strdup(tmp);
  180. }
  181. return NULL;
  182. }
  183. char *GetLaunchTimeOption(char *launchTime) {
  184. if (launchTime != NULL) {
  185. static char tmp[MAXPATHLEN];
  186. char * ptr = strstr(launchTime, "=");
  187. sysStrNPrintF(tmp, sizeof(tmp), "-Djnlp.launchTime%s", (ptr == NULL ? "=NULL" : ptr));
  188. return tmp;
  189. }
  190. return NULL;
  191. }
  192. char* GetPluginBootClassPath(void) {
  193. static char tmp[2 * MAXPATHLEN];
  194. sysStrNPrintF(tmp, sizeof(tmp), "%s%c%s%c%s%c%s%c%s%c%s",
  195. sysGetJarLib(), FILE_SEPARATOR, "javaws.jar",
  196. PATH_SEPARATOR, sysGetJarLib(), FILE_SEPARATOR, "deploy.jar",
  197. PATH_SEPARATOR, sysGetJarLib(), FILE_SEPARATOR, "plugin.jar");
  198. return tmp;
  199. }
  200. char* GetPluginBootClassPathArg(void) {
  201. static char tmp[MAXPATHLEN];
  202. sysStrNPrintF(tmp, sizeof(tmp), "-Xbootclasspath/a:%s",GetPluginBootClassPath());
  203. return tmp;
  204. }
  205. char* GetBootClassPath(void) {
  206. static char tmp[2 * MAXPATHLEN];
  207. sysStrNPrintF(tmp, sizeof(tmp), "%s%c%s%c%s%c%s",
  208. sysGetJarLib(), FILE_SEPARATOR, "javaws.jar",
  209. PATH_SEPARATOR, sysGetJarLib(), FILE_SEPARATOR, "deploy.jar");
  210. return tmp;
  211. }
  212. /* Get the arg for -Xbootclasspath */
  213. char* GetBootClassPathArg(void) {
  214. static char tmp[MAXPATHLEN];
  215. sysStrNPrintF(tmp, sizeof(tmp), "-Xbootclasspath/a:%s",GetPluginBootClassPath());
  216. return tmp;
  217. }
  218. char * GetNonBootClassPath(void) {
  219. static char tmp[MAXPATHLEN];
  220. sysStrNPrintF(tmp, sizeof(tmp), "%s%c%s",
  221. sysGetJarLib(), FILE_SEPARATOR, "deploy.jar");
  222. return tmp;
  223. }
  224. /* get the entire classpath (boot, + regular) */
  225. char * GetDeployJarPath(void) {
  226. static char tmp[MAXPATHLEN];
  227. sysStrNPrintF(tmp, sizeof(tmp), "%s%c%s",
  228. sysGetJarLib(), FILE_SEPARATOR, "deploy.jar");
  229. return tmp;
  230. }
  231. char* GetMozExtDir(char* mozExtDir) {
  232. static char tmp[MAXPATHLEN];
  233. if ((mozExtDir != NULL) && (strlen(mozExtDir) > 0)) {
  234. sysStrNPrintF(tmp, sizeof(tmp), "-Djava.ext.dirs=%s%c%s%c%s%c%s",
  235. sysGetJarLib(),FILE_SEPARATOR, "ext", PATH_SEPARATOR,
  236. mozExtDir, FILE_SEPARATOR, "jss");
  237. return tmp;
  238. }
  239. return NULL;
  240. }
  241. char* GetJnlpxHomeOption(void) {
  242. static char tmp[MAXPATHLEN];
  243. sysStrNPrintF(tmp, sizeof(tmp), "-Djnlpx.home=%s", sysGetApplicationHome());
  244. return tmp;
  245. }
  246. char* GetJnlpxSplashPortOption() {
  247. static char tmp[MAXPATHLEN];
  248. sysStrNPrintF(tmp, sizeof(tmp), "-Djnlpx.splashport=%d", GetSplashPort());
  249. return tmp;
  250. }
  251. char* GetJnlpxJVMOption(char* path) {
  252. static char tmp[MAXPATHLEN];
  253. char * option=NULL;
  254. int n;
  255. if(sysGetQuotesWholePropertySpec()) {
  256. n = sysStrNPrintF(tmp, sizeof(tmp), "-Djnlpx.jvm=%s", path);
  257. if(0<=n && n<sizeof(tmp)) {
  258. option=sysQuoteString(tmp);
  259. }
  260. } else {
  261. char *pathQ = sysQuoteString(path);
  262. n = sysStrNPrintF(tmp, sizeof(tmp), "-Djnlpx.jvm=%s", pathQ);
  263. if(0<=n && n<sizeof(tmp)) {
  264. option=strdup(tmp);
  265. }
  266. free(pathQ);
  267. }
  268. return option;
  269. }
  270. char* GetJnlpxRemoveOption(int copiledFile) {
  271. static char option[MAXPATHLEN];
  272. sysStrNPrintF(option, sizeof(option), "-Djnlpx.remove=%s", (copiledFile) ? "true" : "false");
  273. return option;
  274. }
  275. char* GetSecurityPolicyOption(void) {
  276. static char option[MAXPATHLEN];
  277. sysStrNPrintF(option, sizeof(option), "-Djava.security.policy=file:%s%cjavaws.policy",
  278. sysGetSecurityLib(), FILE_SEPARATOR);
  279. return option;
  280. }
  281. char* GetTrustProxyOption(void) {
  282. static char option[MAXPATHLEN];
  283. sysStrNPrintF(option, sizeof(option), "-DtrustProxy=true");
  284. return option;
  285. }
  286. char* GetVerifierOption(void) {
  287. static char option[MAXPATHLEN];
  288. sysStrNPrintF(option, sizeof(option), "-Xverify:remote");
  289. return option;
  290. }
  291. char* GetHeadlessOption(void) {
  292. static char option[MAXPATHLEN];
  293. sysStrNPrintF(option, sizeof(option), "-Djava.awt.headless=true");
  294. return option;
  295. }
  296. void java_arg_addArg(char *arg, int max_totallen) {
  297. if (arg != NULL && java_arg_count < MAX_COUNT) {
  298. int argLen = strlen(arg);
  299. if ( 0<argLen && (java_arg_strlen+argLen)<max_totallen) {
  300. java_args[java_arg_count] = strdup(arg);
  301. java_arg_count++;
  302. java_arg_strlen+=argLen;
  303. }
  304. }
  305. }
  306. /**
  307. * @param arg - quoted, if necessary
  308. * @param max_totallen maximum length this arg can become,
  309. * note: it will be added 2 times: java_arg_auxargs and java_args!
  310. * @return string.length() <= MAXPATHLEN
  311. */
  312. void java_arg_addAux(char *arg, int max_totallen) {
  313. if (strlen(arg) < max_totallen) {
  314. if (java_arg_auxargs == NULL) {
  315. java_arg_auxargs = strdup(arg);
  316. } else {
  317. int newLen = strlen(arg) + strlen(java_arg_auxargs) + 2;
  318. if(newLen<max_totallen) {
  319. char *new = malloc (newLen);
  320. sysStrNPrintF(new, newLen, "%s %s", java_arg_auxargs, arg);
  321. free(java_arg_auxargs);
  322. java_arg_auxargs = new;
  323. }
  324. }
  325. java_arg_addArg(arg, max_totallen);
  326. }
  327. }
  328. void java_arg_initArgs() {
  329. char *str;
  330. java_arg_addArg(GetBootClassPathArg(), CMDLNMAXLEN);
  331. java_arg_addArg("-classpath", CMDLNMAXLEN);
  332. java_arg_addArg(GetNonBootClassPath(), CMDLNMAXLEN);
  333. java_arg_addArg(GetSecurityPolicyOption(), CMDLNMAXLEN);
  334. java_arg_addArg(GetTrustProxyOption(), CMDLNMAXLEN);
  335. java_arg_addArg(GetVerifierOption(), CMDLNMAXLEN);
  336. java_arg_addArg(GetJnlpxHomeOption(), CMDLNMAXLEN);
  337. java_arg_addArg(GetProfileOption(getenv("USER_JPI_PROFILE")), CMDLNMAXLEN);
  338. java_arg_addArg(GetMozExtDir(getenv("MOZILLA_HOME")), CMDLNMAXLEN);
  339. // always add "AWT warmup" property
  340. // laucher may ignore this parameter depending on platform and other settings
  341. java_arg_addArg("-Dsun.awt.warmup=true", CMDLNMAXLEN);
  342. str = getenv("JAVAWS_VM_ARGS");
  343. if (str != NULL) {
  344. char *arg;
  345. while(*str) {
  346. /* Skip leading withspace */
  347. while(iswspace(*str)) str++;
  348. if (*str) {
  349. arg = str;
  350. /* skip argument (change first whitespace to 0) */
  351. while(*str && !iswspace(*str)) {
  352. str++;
  353. }
  354. if (*str) {
  355. *str++ = '\0';
  356. }
  357. java_arg_addAux(arg, CMDLNMAXLEN);
  358. }
  359. }
  360. }
  361. }
  362. void java_arg_setFile(char *filename, int remove) {
  363. java_arg_Filename = strdup(filename);
  364. java_arg_addArg(GetJnlpxRemoveOption(remove), CMDLNMAXLEN);
  365. }
  366. void java_arg_addHeap(char *initialHeap, char *maxHeap) {
  367. char str[MAXPATHLEN];
  368. if ((initialHeap != NULL) || (maxHeap != NULL)) {
  369. if (initialHeap != NULL && (strlen(initialHeap) < (MAXPATHLEN/4))) {
  370. sysStrNPrintF(str, sizeof(str), "-Xms%s",initialHeap);
  371. java_arg_addArg(str, CMDLNMAXLEN);
  372. } else {
  373. initialHeap = NULL;
  374. }
  375. if (maxHeap != NULL && (strlen(maxHeap) < (MAXPATHLEN/4))) {
  376. sysStrNPrintF(str, sizeof(str), "-Xmx%s",maxHeap);
  377. java_arg_addArg(str, CMDLNMAXLEN);
  378. } else {
  379. maxHeap = NULL;
  380. }
  381. sysStrNPrintF(str, sizeof(str), "-Djnlpx.heapsize=%s,%s",
  382. (initialHeap == NULL ? "NULL" : initialHeap),
  383. (maxHeap == NULL ? "NULL" : maxHeap));
  384. java_arg_addArg(str, CMDLNMAXLEN);
  385. }
  386. }
  387. /*
  388. * SingleInstance implementation
  389. */
  390. int SetupSingleInstance(char *jnlpfile, char* canonicalHome,
  391. int argc, char** argv) {
  392. FILE* sisIN = NULL;
  393. char* magicword = "javaws.singleinstance.init";
  394. char* magicword_openprint = "javaws.singleinstance.init.openprint";
  395. char* eof = "EOF";
  396. char* ack = "javaws.singleinstance.ack";
  397. char sispath[MAXPATHLEN];
  398. int port;
  399. int ret;
  400. char* ret_s;
  401. SOCKET s;
  402. int i;
  403. char* sisProperties;
  404. int size;
  405. char* arg1 = NULL;
  406. char* arg2 = NULL;
  407. char* number;
  408. int a = 0;
  409. while (a < argc - 1) {
  410. if (strcmp(argv[a], "-open") == 0 || strcmp(argv[a], "-print") == 0) {
  411. arg1 = argv[a];
  412. arg2 = argv[++a];
  413. break;
  414. }
  415. a++;
  416. }
  417. port = sysFindSiPort(canonicalHome);
  418. if (port != -1) {
  419. /* talk to single instance server */
  420. s = sysCreateClientSocket(port);
  421. if (s == INVALID_SOCKET) {
  422. return 0;
  423. }
  424. number = sysFindSiNumber(canonicalHome);
  425. if (number == NULL) {
  426. return 0;
  427. }
  428. /* send si random number */
  429. ret = sysWriteSocket(s, number);
  430. if (ret == 0) {
  431. return 0;
  432. }
  433. /* send MAGICWORD */
  434. if (arg1 != NULL && arg2 != NULL) {
  435. ret = sysWriteSocket(s, magicword_openprint);
  436. if (ret == 0) {
  437. return 0;
  438. }
  439. /* send over the open print arguments */
  440. ret = sysWriteSocket(s, arg1);
  441. if (ret == 0) {
  442. return 0;
  443. }
  444. ret = sysWriteSocket(s, arg2);
  445. if (ret == 0) {
  446. return 0;
  447. }
  448. } else {
  449. ret = sysWriteSocket(s, magicword);
  450. if (ret == 0) {
  451. return 0;
  452. }
  453. /* send over the jnlp file */
  454. ret = sysWriteSocket(s, jnlpfile);
  455. if (ret == 0) {
  456. return 0;
  457. }
  458. }
  459. /* incicate EOF */
  460. ret = sysWriteSocket(s, eof);
  461. if (ret == 0) {
  462. return 0;
  463. }
  464. /* wait for ack from server */
  465. /* try read socket for 5 times - do we need to retry at all? */
  466. for (i = 0; i< 5; i++) {
  467. ret_s = sysReadSocket(s);
  468. if (ret_s != NULL && strcmp(ret_s, ack) == 0) {
  469. /* if acked, exit program */
  470. sysCloseSocket(s);
  471. return 1;
  472. }
  473. }
  474. sysCloseSocket(s);
  475. }
  476. return 0;
  477. }
  478. void showUsage() {
  479. sysMessage(getMsgString(MSG_JAVAWS_USAGE));
  480. }
  481. /*
  482. *
  483. * Main Entry Point.
  484. *
  485. */
  486. int main(int argc, char** argv) {
  487. char* jreversion = NULL;
  488. char* jrelocation = NULL;
  489. int jreIndex = 0;
  490. int copiedfile = FALSE;
  491. int wait = FALSE;
  492. int silent = FALSE;
  493. int import = FALSE;
  494. int uninstall = FALSE;
  495. int isViewer = FALSE;
  496. int isSystem = FALSE;
  497. int doSplash = TRUE;
  498. int verbose = FALSE;
  499. int nverbose = FALSE;
  500. int copyTmp = TRUE;
  501. char* splash = NULL;
  502. char* jnlbuffer = NULL;
  503. char *filename = NULL;
  504. char *copyfilename = NULL;
  505. int i, ret, len, size;
  506. int bExists, bUpdated, bIsCurrent;
  507. char* perflog = NULL;
  508. char* launchTime = NULL;
  509. JNLFile *jnlfile = NULL;
  510. int custCmdMaxLen;
  511. char javaExe[MAXPATHLEN] = {0};
  512. int startTime = sysSetStartTime();
  513. /*
  514. * Platform-specific setup.
  515. */
  516. LauncherSetup_md(argv);
  517. /*
  518. * Handle "javaws -splash <port> <image file>" here, and then exit
  519. */
  520. if ((argc >= 3) && (strcmp("-splash", argv[1]) == 0)) {
  521. int port = atoi(argv[2]);
  522. ret = sysSplash(port, argv[3]);
  523. exit(0);
  524. }
  525. if (getenv("JAVAWS_TRACE_NATIVE") != NULL) {
  526. verbose = TRUE;
  527. nverbose = TRUE;
  528. }
  529. /* Load configuration file into memory */
  530. bExists = LoadConfigurationFile(nverbose);
  531. /* rescan system registry for new or removed JREs */
  532. bUpdated = RescanJREs(nverbose);
  533. /*
  534. * Handle "javaws -userConfig <property name> [<property-value>]" here,
  535. * and then exit
  536. */
  537. if (argc > 2) {
  538. if (strcmp("-userConfig", argv[1]) == 0) {
  539. if (argc == 4) {
  540. SetProperty(argv[2], argv[3]);
  541. } else if (argc == 3) {
  542. SetProperty(argv[2], NULL);
  543. }
  544. StoreConfigurationFile(nverbose);
  545. exit(0);
  546. }
  547. }
  548. /* Find first non-option argument */
  549. for(i = 1; i < argc && filename == NULL; i++) {
  550. len = strlen(argv[i]);
  551. if (len > 0) {
  552. if (*argv[i] != '-') {
  553. filename = argv[i];
  554. argv[i] = "";
  555. } else if (!strcmp("-uninstall", argv[i])) {
  556. uninstall = TRUE;
  557. doSplash = FALSE;
  558. wait = TRUE;
  559. } else if (!strcmp("-Xclearcache", argv[i])) {
  560. uninstall = TRUE;
  561. doSplash = FALSE;
  562. wait = TRUE;
  563. argv[i] = "-uninstall";
  564. } else if (!strcmp("-Xnosplash", argv[i])) {
  565. doSplash = FALSE;
  566. argv[i] = "";
  567. } else if (!strcmp("-verbose", argv[i])) {
  568. verbose = TRUE;
  569. argv[i] = "";
  570. } else if (!strcmp("-import", argv[i])) {
  571. wait = TRUE;
  572. import = TRUE;
  573. } else if (!strcmp("-wait", argv[i])) {
  574. wait = TRUE;
  575. } else if (!strcmp("-silent", argv[i])) {
  576. silent = TRUE;
  577. } else if (!strcmp("-codebase", argv[i])) {
  578. /* skip the next arg */
  579. i++;
  580. } else if (!strcmp("-docbase", argv[i])) {
  581. /* skip the next arg */
  582. i++;
  583. } else if (!strcmp("-open", argv[i])) {
  584. /* skip the next arg */
  585. i++;
  586. } else if (!strcmp("-print", argv[i])) {
  587. /* skip the next arg */
  588. i++;
  589. } else if (strstr(argv[i], "-perflog=file:") &&
  590. strlen(argv[i]) > strlen("-perflog=file:")) {
  591. perflog = strdup(argv[i]);
  592. } else if (strstr(argv[i], "-launchTime=") &&
  593. strlen(argv[i]) > strlen("-launchTime=")) {
  594. launchTime = strdup(argv[i]);
  595. } else if (!strncmp("-J", argv[i], strlen("-J"))) {
  596. } else if (!strcmp("-timestamp", argv[i])) {
  597. /* skip the next arg */
  598. i++;
  599. } else if (!strcmp("-expiration", argv[i])) {
  600. /* skip the next arg */
  601. i++;
  602. } else if (!strcmp("-viewer", argv[i])) {
  603. isViewer = TRUE;
  604. doSplash = FALSE;
  605. } else if (!strcmp("-system", argv[i])) {
  606. isSystem = TRUE;
  607. } else if (!strcmp("-quiet", argv[i])) {
  608. doSplash = FALSE;
  609. } else if (!strcmp("-localfile", argv[i]) ||
  610. !strcmp("-draggedApplet", argv[i])) {
  611. /* -draggedApplet is legacy from 6u10 and 6u11
  612. treat as -localfile */
  613. copyTmp = FALSE;
  614. } else if (!strcmp("-online", argv[i])) {
  615. } else if (!strcmp("-installer", argv[i])) {
  616. } else if (!strcmp("-association", argv[i])) {
  617. } else if (!strcmp("-shortcut", argv[i])) {
  618. } else if (!strcmp("-secure", argv[i])) {
  619. } else if (!strcmp("-reverse", argv[i])) {
  620. } else if (!strcmp("-javafx", argv[i])) {
  621. } else if (!strcmp("-javafxau", argv[i])) {
  622. } else if (!strcmp("-prompt", argv[i])) {
  623. } else if (!strcmp("-offline", argv[i])) {
  624. } else if (!strcmp("-quick", argv[i])) {
  625. } else if (!strncmp("-X", argv[i], strlen("-X"))) {
  626. } else {
  627. showUsage();
  628. exit (-1);
  629. }
  630. }
  631. }
  632. /*
  633. * if uninstalling, and sysGetDeploymentUserHome() dosn't exist,
  634. * just exit (before StoreConfigurationFile() will create home dir)
  635. */
  636. if (uninstall & !isSystem) {
  637. struct stat statBuf;
  638. if (stat(sysGetDeploymentUserHome(), &statBuf) < 0) {
  639. exit(0);
  640. }
  641. }
  642. /* store the user-specific configuration file changes resulting from
  643. * the rescan of registry
  644. */
  645. if (bUpdated || !bExists) {
  646. StoreConfigurationFile(nverbose);
  647. }
  648. /*
  649. * Handle "javaws -quick" - exit after rescan of jres
  650. */
  651. if ((argc == 2) && (strcmp("-quick", argv[1]) == 0)) {
  652. /* just wanted to update config file with new jre(s) */
  653. exit(0);
  654. }
  655. /*
  656. * several error conditions
  657. * 1 - can not be both system and viewer
  658. * 2 - if arg required following arg that wasn't there
  659. * 3 - no jnlp file or url, and not viewer or uninstall
  660. */
  661. if ((isViewer && isSystem) ||
  662. (i > argc) ||
  663. (!isViewer && !isSystem && !uninstall && (filename == NULL))) {
  664. showUsage();
  665. exit (-1);
  666. }
  667. /* only enable silent mode if import or uninstall */
  668. if((import == TRUE || uninstall == TRUE) && silent == TRUE) {
  669. doSplash = FALSE;
  670. } else {
  671. silent = FALSE;
  672. }
  673. java_arg_initArgs();
  674. sysSetupQuotesWholePropertySpec(nverbose);
  675. /*
  676. * OK, do we have a filename or a url argument ?
  677. */
  678. if (filename != NULL) {
  679. /* pass in original filename argument to Java side */
  680. /* this is needed because if we launch with a local jnlp file, we
  681. need the original filename to figure out the relative codebase.
  682. by default, the launcher will always make a copy of the jnlp file,
  683. and pass that to main (Java) of Java Web Start */
  684. char *prefix = "-Djnlpx.origFilenameArg=";
  685. int len = strlen(prefix) + strlen(filename) + 1;
  686. char *origFilenameArg = (char*)malloc(sizeof(char) * len);
  687. if (origFilenameArg != NULL) {
  688. int ret = sysStrNPrintF(origFilenameArg, len, "%s%s", prefix,
  689. filename);
  690. if (ret != -1) {
  691. java_arg_addArg(origFilenameArg, CMDLNMAXLEN);
  692. }
  693. }
  694. /* If uninstalling or importing, no need to copy and no need to parse
  695. * the file for the JRE to use, we can use default.
  696. */
  697. if (uninstall == TRUE || import == TRUE) {
  698. java_arg_setFile(filename, FALSE);
  699. jnlfile = ParseJNLFile(NULL, nverbose);
  700. } else {
  701. /*
  702. * We need to read, copy, parse the given jnlp file (if possible)
  703. */
  704. size = ReadFileToBuffer(filename, &jnlbuffer);
  705. if (jnlbuffer != NULL) {
  706. if (copyTmp) {
  707. /*
  708. * Create a copy of the file
  709. */
  710. copyfilename = sysTempnam();
  711. if (SaveBufferToFile(copyfilename, jnlbuffer, size) == FALSE) {
  712. /* Ignore error - just did not make a copy */
  713. if (TRUE == verbose) {
  714. Message("Failed to copy argument");
  715. Message(copyfilename);
  716. }
  717. java_arg_setFile(filename, FALSE);
  718. } else {
  719. /*
  720. * Update arguments to have a reference to the copy
  721. */
  722. java_arg_setFile(copyfilename, TRUE);
  723. }
  724. } else {
  725. // -localfile specified (copyTmp is FALSE)
  726. // use cached JNLP directly, no need to remove
  727. java_arg_setFile(filename, FALSE);
  728. }
  729. /* Extract jre version out of option file */
  730. if (isUTF8(jnlbuffer, size)) {
  731. jnlfile = ParseJNLFile(jnlbuffer, nverbose);
  732. } else {
  733. /*
  734. * arg is non utf-8 - cannot parse
  735. */
  736. jnlfile = ParseJNLFile(NULL, nverbose);
  737. jnlfile->isPlayer = FALSE;
  738. }
  739. } else {
  740. /*
  741. * arg is url, not a file - cannot read or parse
  742. */
  743. jnlfile = ParseJNLFile(NULL, nverbose);
  744. jnlfile->jnlp_url = filename;
  745. jnlfile->isPlayer = FALSE;
  746. java_arg_setFile(filename, FALSE);
  747. }
  748. }
  749. } else {
  750. /*
  751. * filename (or url) arg is NULL
  752. */
  753. jnlfile = ParseJNLFile(NULL, nverbose);
  754. jnlfile->isPlayer = TRUE;
  755. }
  756. custCmdMaxLen = CMDLNMAXLEN - java_arg_strlen - 8 /* safety */;
  757. custCmdMaxLen -= strlen(JAVAWS_MAIN_CLASS);
  758. for (i=1; i<argc; i++) {
  759. if (argv[i] != NULL) {
  760. custCmdMaxLen -=strlen(argv[i]);
  761. }
  762. }
  763. if(java_arg_Filename!=NULL) {
  764. custCmdMaxLen -= strlen(java_arg_Filename);
  765. }
  766. /*
  767. * now that we have jnlfile structure, use various info from it.
  768. */
  769. for (i=0; i<jnlfile->auxArgCount; i++) {
  770. if (jnlfile->auxArg[i] != NULL) {
  771. java_arg_addAux(jnlfile->auxArg[i], custCmdMaxLen/2);
  772. }
  773. }
  774. for (i = 0; i < jnlfile->auxPropCount; i++) {
  775. java_arg_addAux(jnlfile->auxProp[i], custCmdMaxLen/2);
  776. }
  777. java_arg_addHeap(jnlfile->initialHeap, jnlfile->maxHeap);
  778. if (silent) {
  779. java_arg_addArg("-Djava.awt.headless=true", custCmdMaxLen);
  780. }
  781. // splash preference: 0 = normal, 1 = never, 2 = no default (custom only)
  782. if (jnlfile->splashPref == SPLASH_NEVER) {
  783. doSplash = FALSE;
  784. }
  785. if (doSplash == TRUE) {
  786. if ((jnlfile->canonicalHome != NULL) || (jnlfile->jnlp_url != NULL)) {
  787. getAppSplashFiles(jnlfile, &splash);
  788. } else {
  789. getDefaultSplashFiles(jnlfile->isPlayer, &splash);
  790. }
  791. }
  792. if (perflog != NULL) {
  793. java_arg_addArg(GetPerfLogOption(perflog), custCmdMaxLen);
  794. java_arg_addArg(GetStartTimeOption(startTime), custCmdMaxLen);
  795. }
  796. if (launchTime != NULL) {
  797. java_arg_addArg(GetLaunchTimeOption(launchTime), custCmdMaxLen);
  798. }
  799. /*
  800. * OK - now determine version of java to run
  801. */
  802. if (jnlfile->jreVersion != NULL) {
  803. jreversion = strdup(jnlfile->jreVersion);
  804. if (jnlfile->jreLocation != NULL) {
  805. jrelocation = strdup(jnlfile->jreLocation);
  806. }
  807. }
  808. if (jnlfile->canonicalHome != NULL) {
  809. /*
  810. * try to setup single instance service
  811. */
  812. ret = SetupSingleInstance(jnlbuffer, jnlfile->canonicalHome,
  813. argc, argv);
  814. if (ret == 1) {
  815. /* Free allocated memory */
  816. FreeJNLFile(jnlfile);
  817. if (jnlbuffer != NULL) {
  818. free(jnlbuffer);
  819. }
  820. sysExit(copyfilename);
  821. }
  822. }
  823. /*
  824. * A NULL jreversions implies we should use the default, otherwise map the
  825. * the version string to a valid version and look up the location of the
  826. * VM.
  827. */
  828. if (jreversion == NULL) {
  829. jreversion = getDefaultJREs(); /* pref is to use latest */
  830. /* use default JRE location if nothing is specified */
  831. jrelocation = strdup(DEFHREF);
  832. }
  833. jreIndex = DetermineVersion(jreversion, jrelocation, nverbose);
  834. /* check EULA for win32 platforms */
  835. if (EULA_md(argc, argv, jnlfile->isPlayer) != 1) {
  836. sysExit(copyfilename);
  837. }
  838. /* Free allocated memory */
  839. FreeJNLFile(jnlfile);
  840. if (jnlbuffer != NULL) {
  841. free(jnlbuffer);
  842. }
  843. if (doSplash) {
  844. char *error = ShowSplashScreen(splash);
  845. if (error != NULL) {
  846. if (silent) {
  847. exit(-1);
  848. } else {
  849. Abort(error);
  850. }
  851. }
  852. java_arg_addArg(GetJnlpxSplashPortOption(), custCmdMaxLen);
  853. }
  854. java_arg_command = GetJREJavaCmd(jreIndex);
  855. if (java_arg_command == NULL) {
  856. /* This should never happen */
  857. if (silent) {
  858. exit(-1);
  859. } else {
  860. Abort(getMsgString(MSG_BADINST_NOJRE));
  861. }
  862. }
  863. java_args[0] = java_arg_command; /* we saved index 0 for exec path */
  864. for (i=1; i<argc; i++) {
  865. // remaining -J args go before the main class
  866. if ((argv[i] != NULL) && (!strncmp("-J", argv[i], 2))) {
  867. if (strlen(argv[i]) > 2) {
  868. java_arg_addAux(argv[i] + 2, custCmdMaxLen/2);
  869. }
  870. argv[i] = "";
  871. }
  872. }
  873. java_arg_addArg(GetJnlpxJVMOption(java_arg_command), custCmdMaxLen);
  874. java_arg_addArg(GetVMArgsOption(java_arg_auxargs), custCmdMaxLen);
  875. java_arg_addArg(JAVAWS_MAIN_CLASS, CMDLNMAXLEN);
  876. for (i=1; i<argc; i++) {
  877. // remaining args go after the main class. remove "-localfile"
  878. // since it is not used in Main
  879. if (argv[i] != NULL && strcmp("-localfile", argv[i])) {
  880. // no need to quote the string again, the whole string is already
  881. // treated as a separate argument
  882. java_arg_addArg(argv[i], CMDLNMAXLEN);
  883. }
  884. }
  885. // final arg is the jnlp file
  886. java_arg_addArg(java_arg_Filename, CMDLNMAXLEN);
  887. if(nverbose) {
  888. printf("total cmdline length: %d\n", java_arg_strlen);
  889. printf("total arguments: : %d\n", java_arg_count);
  890. }
  891. assert((java_arg_count < MAX_COUNT - 1), "too many java args to run");
  892. if (verbose) {
  893. int i;
  894. char message[CMDLNMAXLEN+1];
  895. strcpy(message, "Launching: ");
  896. strcat(message, java_arg_command);
  897. strcat(message, "\n");
  898. for(i=0; i < java_arg_count; i++) {
  899. if (java_args[i] != NULL) {
  900. strcat(message, java_args[i]);
  901. strcat(message, "\n");
  902. }
  903. strcat(message, " ");
  904. }
  905. strcat(message, "\n");
  906. sysMessage(message);
  907. }
  908. /*
  909. * Spawn the java launcher
  910. */
  911. if (wait) {
  912. if (sysExec(SYS_EXEC_WAIT, java_arg_command, java_args) == -1) {
  913. if (silent) {
  914. exit(-1);
  915. } else {
  916. char *msg = malloc(2*MAXPATHLEN);
  917. sysStrNPrintF(msg, 2*MAXPATHLEN, "%s \n%s",
  918. getMsgString(MSG_BADINST_EXECV), java_arg_command);
  919. Abort(msg);
  920. }
  921. }
  922. } else {
  923. if (sysExec(SYS_EXEC_FORK, java_arg_command, java_args) == -1) {
  924. if (silent) {
  925. exit(-1);
  926. } else {
  927. char *msg = malloc(2*MAXPATHLEN);
  928. sysStrNPrintF(msg, 2*MAXPATHLEN, "%s \n%s",
  929. getMsgString(MSG_BADINST_SYSEXE), java_arg_command);
  930. Abort(msg);
  931. }
  932. }
  933. }
  934. sysSetEndTime();
  935. if (verbose) {
  936. sysPrintTimeUsed(perflog);
  937. }
  938. return 0;
  939. }