PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/carrot-garden/carrot-jnlper
C | 509 lines | 410 code | 39 blank | 60 comment | 49 complexity | 44d84db7d69b2ed3a80b053c5ed9a27c MD5 | raw file
  1. /*
  2. * @(#)system.c 1.25 10/03/24
  3. *
  4. * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
  5. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /* Implementation of shared system code. This code is the same
  8. * for all platforms.
  9. */
  10. #include "system.h"
  11. /*
  12. * Create a loopback socket and set it up to listen on a dynamically
  13. * allocated "ephemeral" port. Return the port and a new socket or
  14. * INVALID_SOCKET if there's an error.
  15. */
  16. SOCKET sysCreateListenerSocket(int *port)
  17. {
  18. SOCKET server;
  19. SOCKADDR_IN iname = {0};
  20. int length = sizeof(iname);
  21. sysInitSocketLibrary();
  22. iname.sin_family = AF_INET;
  23. iname.sin_addr.s_addr = inet_addr("127.0.0.1");
  24. if ((server = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  25. return INVALID_SOCKET;
  26. }
  27. if (bind(server, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) {
  28. sysCloseSocket(server);
  29. return INVALID_SOCKET;
  30. }
  31. if (getsockname(server, (SOCKADDR *)&iname, &length) == SOCKET_ERROR) {
  32. sysCloseSocket(server);
  33. return INVALID_SOCKET;
  34. }
  35. if (listen(server, SOMAXCONN) == SOCKET_ERROR) {
  36. sysCloseSocket(server);
  37. return INVALID_SOCKET;
  38. }
  39. *port = ntohs(iname.sin_port);
  40. return server;
  41. }
  42. /*
  43. * Create a loopback socket and set it up to listen on the specified
  44. * port. Return the new socket or INVALID_SOCKET if there's an error.
  45. */
  46. SOCKET sysCreateServerSocket(int port)
  47. {
  48. SOCKET server;
  49. SOCKADDR_IN iname = {0};
  50. int length = sizeof(iname);
  51. sysInitSocketLibrary();
  52. iname.sin_family = AF_INET;
  53. iname.sin_port = htons((u_short)port);
  54. iname.sin_addr.s_addr = inet_addr("127.0.0.1");
  55. if ((server = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  56. return INVALID_SOCKET;
  57. }
  58. if (bind(server, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) {
  59. sysCloseSocket(server);
  60. return INVALID_SOCKET;
  61. }
  62. if (listen(server, SOMAXCONN) == SOCKET_ERROR) {
  63. sysCloseSocket(server);
  64. return INVALID_SOCKET;
  65. }
  66. return server;
  67. }
  68. /*
  69. * Create a loopback socket connected to the specified port. Return the
  70. * new socket or INVALID_SOCKET if there's an error.
  71. */
  72. SOCKET sysCreateClientSocket(int port)
  73. {
  74. SOCKET client;
  75. SOCKADDR_IN iname = {0};
  76. sysInitSocketLibrary();
  77. iname.sin_family = AF_INET;
  78. iname.sin_port = htons((u_short)port);
  79. iname.sin_addr.s_addr = inet_addr("127.0.0.1");
  80. if ((client = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  81. return INVALID_SOCKET;
  82. }
  83. if (connect(client, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) {
  84. sysCloseSocket(client);
  85. return INVALID_SOCKET;
  86. }
  87. return client;
  88. }
  89. /*
  90. * Tests creatability of a loopback socket for the specified port.
  91. * If the test fails, INVALID_SOCKET is returned, otherwise the
  92. * would-be socket is returned. For the special case *port == 0,
  93. * the port will be reset to an ephemeral port (chosen by the kernel).
  94. */
  95. SOCKET sysTestServerSocketCreatable(int* port)
  96. {
  97. SOCKET sock;
  98. SOCKADDR_IN iname = {0};
  99. int length = sizeof(iname);
  100. sysInitSocketLibrary();
  101. iname.sin_family = AF_INET;
  102. iname.sin_port = htons((u_short)*port);
  103. iname.sin_addr.s_addr = inet_addr("127.0.0.1");
  104. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  105. return INVALID_SOCKET;
  106. }
  107. /* When bind() is called and *port==0, kernel will choose ephemeral port */
  108. if (bind(sock, (SOCKADDR *)&iname, sizeof(iname)) == SOCKET_ERROR) {
  109. sysCloseSocket(sock);
  110. return INVALID_SOCKET;
  111. }
  112. /* When getsockname() is called, iname is updated to reflect port used
  113. by kernel */
  114. if (getsockname(sock, (SOCKADDR *)&iname, &length) == SOCKET_ERROR) {
  115. sysCloseSocket(sock);
  116. return INVALID_SOCKET;
  117. }
  118. /* At this juncture, we have a valid socket and a valid (possibly
  119. ephemeral) port */
  120. *port = ntohs(iname.sin_port);
  121. sysCloseSocket(sock);
  122. return sock;
  123. }
  124. /*
  125. * Write a short string to the socket, adding a "\r\n" at the end. If
  126. * an error occurs, 0 is returned.
  127. */
  128. int sysWriteSocket(SOCKET s, char *str)
  129. {
  130. char* buffer;
  131. int result = 0, len=0;
  132. if (str == NULL) return result;
  133. /* allocate length of str + 3, for str itself, \r\n and \0 by sysStrNPrintF */
  134. len = sizeof(char) * (strlen(str) + 3);
  135. buffer = (char*)malloc(len);
  136. if (buffer == NULL) return result;
  137. sysStrNPrintF(buffer, len, "%s\r\n", str);
  138. result = send(s, buffer, strlen(buffer), 0) != SOCKET_ERROR ;
  139. free(buffer);
  140. return result;
  141. }
  142. /*
  143. * Read a short newline terminated string from the socket or NULL if
  144. * an error occurs. The newline is replaced with a null character.
  145. * The returned value is a pointer to a single static buffer so callers
  146. * should copy the returned string if they need to hold on to it.
  147. */
  148. char *sysReadSocket(SOCKET s)
  149. {
  150. static char buffer[1024];
  151. int count = 0;
  152. int r;
  153. do {
  154. r = recv(s, &buffer[count], 1, 0);
  155. if (r == SOCKET_ERROR) return NULL;
  156. if (r == 0 || buffer[count] == '\n') {
  157. buffer[count] = '\0';
  158. return buffer;
  159. }
  160. if (buffer[count] != '\r') count++;
  161. }
  162. while(count < sizeof(buffer) - 1);
  163. /* Buffer overflow. Just return the part we read */
  164. buffer[sizeof(buffer)-1] = '\0';
  165. return buffer;
  166. }
  167. static int _quoteWholePropertySpec = -1;
  168. void sysSetupQuotesWholePropertySpec(int verbose)
  169. {
  170. char* osName = sysGetOsName();
  171. _quoteWholePropertySpec = sysStrNCaseCmp(osName, "Win", 3)==0;
  172. if(verbose) {
  173. printf("osName: <%s>, osArch<%s>, quoteWholeProperty: %d\n",
  174. osName, sysGetOsArch(), _quoteWholePropertySpec);
  175. }
  176. }
  177. int sysGetQuotesWholePropertySpec()
  178. {
  179. return _quoteWholePropertySpec;
  180. }
  181. /*
  182. * If the string contains spaces and is not quoted already,
  183. * then add double quotes at both ends and escape any internal
  184. * double quotes. Here are some examples of the way this
  185. * function transforms a string:
  186. *
  187. * one two => "one two"
  188. * one "two" three => "one \"two\" three"
  189. * noEmbeddedSpaces => noEmbeddedSpaces
  190. * "already quoted" => "already quoted"
  191. *
  192. * A copy of the string is always returned unless s is NULL,
  193. * then it's just returned as is.
  194. */
  195. char *sysQuoteString(char *s)
  196. {
  197. int length0;
  198. if (!s) {
  199. return s;
  200. }
  201. length0 = strlen(s);
  202. if (strpbrk(s, " \t") == NULL) {
  203. return strdup(s);
  204. }
  205. else if ((length0 > 1) && (s[0] == '"') && (s[length0 - 1] == '"')) {
  206. return strdup(s);
  207. }
  208. else {
  209. int i, j = 0, length1 = length0 + 3;
  210. char *ss;
  211. /* count the number of embedded double quote chars */
  212. for(i = 0; i < length0; i++) {
  213. if (s[i] == '"') {
  214. length1 += 1;
  215. }
  216. }
  217. /* copy s, replacing each '"' with '\"' */
  218. ss = (char *)malloc(length1);
  219. ss[j++] = '"';
  220. for(i = 0; i < length0; i++) {
  221. if (s[i] == '"') {
  222. ss[j++] = '\\';
  223. }
  224. ss[j++] = s[i];
  225. }
  226. ss[j++] = '"';
  227. ss[j] = '\0';
  228. return ss;
  229. }
  230. }
  231. char* sysGetJarLib(void) {
  232. static char path[MAXPATHLEN];
  233. static int initialized = FALSE;
  234. if (!initialized) {
  235. char *appHome = sysGetApplicationHome();
  236. strncpy(path, appHome, strlen(appHome) - 3);
  237. strcat(path, "lib");
  238. initialized = TRUE;
  239. }
  240. return path;
  241. }
  242. char* sysGetJavawsResourcesLib(void) {
  243. static char path[MAXPATHLEN];
  244. static int initialized = FALSE;
  245. if (!initialized) {
  246. char *jarlib = sysGetJarLib();
  247. sysStrNPrintF(path, sizeof(path), "%s%c%s", jarlib, FILE_SEPARATOR, "deploy");
  248. initialized = TRUE;
  249. }
  250. return path;
  251. }
  252. char* sysGetSecurityLib(void) {
  253. static char path[MAXPATHLEN];
  254. static int initialized = FALSE;
  255. if (!initialized) {
  256. char *jarlib = sysGetJarLib();
  257. sysStrNPrintF(path, sizeof(path), "%s%c%s", jarlib, FILE_SEPARATOR, "security");
  258. initialized = TRUE;
  259. }
  260. return path;
  261. }
  262. /* remove temp file on exit */
  263. void sysExit(char *copyfilename) {
  264. if (copyfilename != NULL) {
  265. remove(copyfilename);
  266. }
  267. exit(0);
  268. }
  269. char * sysSaveConvert(unsigned short *theString) {
  270. char* output = (char*)malloc(sizeof(char)*MAXPATHLEN);
  271. int i = 0;
  272. while (*theString != 0) {
  273. if (*theString == 0xFEFF || *theString == 0xFFFE) {
  274. /* skip it */
  275. } else if (*theString < 0x007F) {
  276. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%c", *theString);
  277. i++;
  278. } else {
  279. /* write out unicode in java properties file escaped sequence */
  280. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%c", '\\');
  281. i++;
  282. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%c", 'u');
  283. i++;
  284. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%x", (*theString >> 12) & 0xF );
  285. i++;
  286. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%x", (*theString >> 8) & 0xF );
  287. i++;
  288. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%x", (*theString >> 4) & 0xF);
  289. i++;
  290. sysStrNPrintF(&output[i], MAXPATHLEN-i, "%x", (*theString) & 0xF);
  291. i++;
  292. }
  293. *theString++;
  294. }
  295. return output;
  296. }
  297. void sysReplaceChar(char* orig, char oldChar, char newChar) {
  298. while (*orig != 0) {
  299. if (*orig == oldChar) {
  300. *orig = newChar;
  301. }
  302. *orig++;
  303. }
  304. }
  305. /*
  306. * Append the system dependent si direcotry to the si filename passed in as
  307. * argument. Return the complete path to si filename. If error occurs, NULL
  308. * is returned.
  309. */
  310. char* sysGetSiFilePath (char *siFilename) {
  311. char* siFilePath;
  312. char* deployUserHome;
  313. const char* tmpString = "tmp";
  314. const char* siString = "si";
  315. int ret;
  316. size_t size;
  317. if (siFilename == NULL) {
  318. return NULL;
  319. }
  320. deployUserHome = sysGetDeploymentUserHome();
  321. if (deployUserHome == NULL) {
  322. return NULL;
  323. }
  324. // allocate memory for siFilePath
  325. size = strlen(siFilename) + strlen(deployUserHome) + strlen(tmpString) +
  326. strlen(siString) + 3 + 1;
  327. siFilePath = (char*)malloc(sizeof(char)*size);
  328. if (siFilePath == NULL) {
  329. return NULL;
  330. }
  331. ret = sysStrNPrintF(siFilePath, size, "%s%c%s%c%s%c%s", deployUserHome,
  332. FILE_SEPARATOR, tmpString, FILE_SEPARATOR, siString, FILE_SEPARATOR,
  333. siFilename);
  334. if (0>ret || ret>=size) {
  335. return NULL;
  336. }
  337. return siFilePath;
  338. }
  339. /*
  340. * Given the canonicalHome of the jnlp application, find the random number
  341. * used for single instance application. Returns the random number
  342. * string if found. Otherwise returns NULL.
  343. */
  344. char* sysFindSiNumber(char *canonicalHome) {
  345. char siFilename[MAXPATHLEN];
  346. char *siFilepath;
  347. char *cHomeNoQuery;
  348. char *siNumber = NULL;
  349. int ret;
  350. int index;
  351. FILE* fp = NULL;
  352. char szBuffer[MAXPATHLEN];
  353. int len = MAXPATHLEN;
  354. char *qindex = strrchr(canonicalHome, '?');
  355. if (qindex != NULL) {
  356. index = qindex - canonicalHome;
  357. cHomeNoQuery = (char*)malloc(sizeof(char) * (index + 1));
  358. cHomeNoQuery[index] = '\0';
  359. strncpy(cHomeNoQuery, canonicalHome, index);
  360. } else {
  361. cHomeNoQuery = canonicalHome;
  362. }
  363. ret = sysFindSiFile(cHomeNoQuery, siFilename);
  364. if (ret == 1) {
  365. siFilepath = sysGetSiFilePath(siFilename);
  366. if (siFilepath != NULL) {
  367. if ((fp = fopen(siFilepath, "r")) != NULL) {
  368. int bufLen = 0;
  369. fgets(szBuffer, len, fp);
  370. fclose(fp);
  371. bufLen = strlen(szBuffer);
  372. siNumber = (char*)malloc(sizeof(char) * (bufLen + 1));
  373. if (siNumber != NULL) {
  374. // ensure null termination in worst case
  375. siNumber[bufLen] = '\0';
  376. strncpy(siNumber, szBuffer, bufLen);
  377. }
  378. }
  379. free(siFilepath);
  380. }
  381. }
  382. if (qindex != NULL) {
  383. free(cHomeNoQuery);
  384. }
  385. return siNumber;
  386. }
  387. int sysFindSiPort(char *canonicalHome) {
  388. char siFilename[MAXPATHLEN];
  389. char *cHomeNoQuery;
  390. char *portS;
  391. int port = -1;
  392. int ret;
  393. int index;
  394. char *qindex = strrchr(canonicalHome, '?');
  395. if (qindex != NULL) {
  396. index = qindex - canonicalHome;
  397. cHomeNoQuery = (char*)malloc(sizeof(char) * (index + 1));
  398. cHomeNoQuery[index] = '\0';
  399. strncpy(cHomeNoQuery, canonicalHome, index);
  400. } else {
  401. cHomeNoQuery = canonicalHome;
  402. }
  403. ret = sysFindSiFile(cHomeNoQuery, siFilename);
  404. if (ret == 1) {
  405. portS = strrchr(siFilename, '_');
  406. portS++;
  407. port = atoi((const char*)portS);
  408. }
  409. if (qindex != NULL) {
  410. free(cHomeNoQuery);
  411. }
  412. return port;
  413. }
  414. /* path must be an absolute path, and must not have FILE_SEPARATOR at end */
  415. void recursive_create_directory(char *path) {
  416. char *p, *dir;
  417. struct stat stat_buf;
  418. /* if path already exists then return */
  419. if (stat(path, &stat_buf)==0) return;
  420. /* find previous file separator char from end of string */
  421. p = strrchr(path, FILE_SEPARATOR);
  422. if (p == NULL) return;
  423. /* store before chopping */
  424. dir = strdup(path);
  425. /* chop string at file separator char */
  426. if (p > path && *(p-1) != ':') *p = 0;
  427. else *(p+1) = 0;
  428. /* recurse */
  429. recursive_create_directory(path);
  430. sysCreateDirectory(dir);
  431. free(dir);
  432. }