patch-pid-in-outputToFile-plus-win-fix.diff
src/com/goldencode/p2j/main/ClientCore.java 2023-01-27 13:53:55 +0000 | ||
---|---|---|
2 | 2 |
** Module : ClientCore.java |
3 | 3 |
** Abstract : core client loop which handles init and connects to server |
4 | 4 |
** |
5 |
** Copyright (c) 2005-2022, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2005-2023, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ----------------------------------Description--------------------------------- |
8 | 8 |
** 001 GES 20110928 Moved core logic here from ClientDriver so that the same |
... | ... | |
62 | 62 |
** CA 20220918 Added socket trust store filename and password to the ClientParameters. |
63 | 63 |
** GBB 20221209 Path to debug log file to be read from client bootstrap configs. |
64 | 64 |
** Passing arg to spawner for path to stderr log file for background processes. |
65 |
** GBB 20230127 Fixing pid in outputToFile name by replacing it in Java code. |
|
65 | 66 |
*/ |
66 | 67 |
/* |
67 | 68 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
118 | 119 | |
119 | 120 |
package com.goldencode.p2j.main; |
120 | 121 | |
122 |
import java.io.*; |
|
121 | 123 |
import java.util.*; |
122 | 124 |
import java.util.function.*; |
123 | 125 |
import java.util.logging.*; |
... | ... | |
186 | 188 |
public static void start(BootstrapConfig config, boolean file, boolean single, Supplier<String> diag) |
187 | 189 |
throws Exception |
188 | 190 |
{ |
191 |
// Load native library |
|
192 |
loadNativeLibrary(); |
|
193 |
|
|
194 |
setOutputToFile(config); |
|
195 |
|
|
189 | 196 |
String uuid = config.getString("server", "spawner", "uuid", null); |
190 | 197 |
boolean dbg = config.getBoolean("logging", "debug", "enable", false); |
191 | 198 |
String referrer = config.getString("web", "referrer", "url", null); |
... | ... | |
196 | 203 |
// iterations of the core loop |
197 | 204 |
ScreenDriver<?> driver = (uuid == null) ? null : processTemporaryClient(uuid, config); |
198 | 205 |
|
199 |
// Load native library |
|
200 |
loadNativeLibrary(); |
|
201 |
|
|
202 | 206 |
while (running) |
203 | 207 |
{ |
204 | 208 |
Object context = null; |
... | ... | |
434 | 438 |
return isStop; |
435 | 439 |
} |
436 | 440 | |
441 |
private static void setOutputToFile(BootstrapConfig config) |
|
442 |
{ |
|
443 |
String outputToFile = config.getString("server", "clientConfig", "outputToFile", null); |
|
444 |
if (outputToFile == null) |
|
445 |
{ |
|
446 |
return; |
|
447 |
} |
|
448 |
|
|
449 |
try |
|
450 |
{ |
|
451 |
outputToFile = outputToFile.replace("%pid%", String.valueOf(getPid())); |
|
452 |
System.setOut(new PrintStream(new FileOutputStream(outputToFile), true)); |
|
453 |
} |
|
454 |
catch (Throwable t) |
|
455 |
{ |
|
456 |
System.err.println("ClientCore: Unable to redirect stdout to outputToFile " + outputToFile); |
|
457 |
} |
|
458 |
} |
|
459 | ||
437 | 460 |
/** |
438 | 461 |
* Loads native library and performs required initial steps for P2J library to working. |
439 | 462 |
*/ |
src/com/goldencode/p2j/main/ProcessClientBuilder.java 2023-01-27 13:56:11 +0000 | ||
---|---|---|
2 | 2 |
** Module : ProcessClientBuilder.java |
3 | 3 |
** Abstract : build and start a platform process for P2J process. |
4 | 4 |
** |
5 |
** Copyright (c) 2014-2017, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2014-2023, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ---------------------------------Description---------------------------------- |
8 | 8 |
** 001 CA 20140206 First version. |
... | ... | |
10 | 10 |
** 003 MAG 20140722 Implemented the remote launcher. |
11 | 11 |
** 004 GES 20160219 Moved code to the parent class allowing reuse of the native secure connection |
12 | 12 |
** setup processing. |
13 |
** GBB 20230127 Fixing pid in outputToFile name by passing it as config to spawned client. |
|
13 | 14 |
*/ |
14 | 15 |
/* |
15 | 16 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
132 | 133 |
if (outputToFile != null) |
133 | 134 |
{ |
134 | 135 |
cmd.add("-O"); |
135 |
cmd.add(outputToFile); |
|
136 |
cmd.add("server:clientConfig:outputToFile=" + outputToFile);
|
|
136 | 137 |
} |
137 | 138 | |
138 | 139 |
return cmd; |
139 | 140 |
} |
140 |
} |
|
141 |
} |
src/native/spawn.c 2023-01-27 13:45:24 +0000 | ||
---|---|---|
162 | 162 |
#define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)/* 07777 */ |
163 | 163 |
#endif |
164 | 164 | |
165 |
/* prototypes */ |
|
166 |
void stdout_redirect(); |
|
167 | ||
168 | 165 |
/* Global data */ |
169 | 166 |
struct passwd *pw; |
170 | 167 |
int extra_logging = 0; |
... | ... | |
175 | 172 | |
176 | 173 |
/* Output file name */ |
177 | 174 |
char output_file_name[MAX_FILENAME]; |
175 |
int output_to_file_opt_found = 0; |
|
178 | 176 | |
179 | 177 |
/** |
180 | 178 |
* Use syslog to audit the execution of child processes. |
... | ... | |
400 | 398 |
logMessage(message_buffer); |
401 | 399 |
exit(audit(ERR_SPAWN_CHDIR_WD, "chdir(workdir)")); |
402 | 400 |
} |
403 | ||
404 |
/* Redirect STDOUT if required */ |
|
405 |
if (output_file_name[0] != 0) |
|
406 |
{ |
|
407 |
stdout_redirect(); |
|
408 |
} |
|
409 | 401 |
|
410 | 402 |
/* Execute command */ |
411 | 403 |
exit(execvp(command, argv)); |
... | ... | |
1018 | 1010 |
/* make it 1-based, so it follows the structure of the command line arguments |
1019 | 1011 |
(0 is program name); also, one more position is needed for execvp, which requires for the |
1020 | 1012 |
arguments to be null-terminated. */ |
1021 |
char **arguments = (char**) malloc((length + 2) * sizeof(char*)); |
|
1013 |
char **arguments = (char**) malloc((length + 2 + output_to_file_opt_found) * sizeof(char*));
|
|
1022 | 1014 |
arguments[0] = NULL; |
1023 |
arguments[length + 1] = NULL; |
|
1015 |
arguments[length + 1 + output_to_file_opt_found] = NULL; |
|
1016 | ||
1017 |
if (output_to_file_opt_found == 1) |
|
1018 |
{ |
|
1019 |
int len = strlen(output_file_name) + 1; |
|
1020 |
arguments[length + 1] = (char*) malloc(len * sizeof(char)); |
|
1021 |
memset(arguments[length + 1], '\0', len); |
|
1022 |
strcpy(arguments[length + 1], output_file_name); |
|
1023 |
} |
|
1024 | 1024 |
|
1025 | 1025 |
int i; |
1026 | 1026 |
for (i = 0; i < (int) length; i++) |
... | ... | |
1151 | 1151 |
} |
1152 | 1152 | |
1153 | 1153 |
/** |
1154 |
* Redirect STDOUT to an output file. |
|
1155 |
*/ |
|
1156 |
void stdout_redirect() |
|
1157 |
{ |
|
1158 |
int output_fd; |
|
1159 |
char pid[32]; |
|
1160 |
|
|
1161 |
/* convert pid to string */ |
|
1162 |
sprintf(pid, "%u", getpid()); |
|
1163 |
|
|
1164 |
/* replace %pid% placeholder */ |
|
1165 |
char* filename = replace_str(output_file_name, "%pid%", pid); |
|
1166 |
|
|
1167 |
// Open file |
|
1168 |
output_fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644); |
|
1169 |
|
|
1170 |
if (output_fd == -1) |
|
1171 |
{ |
|
1172 |
fprintf(stderr, "Cannot open file %s\n", filename); |
|
1173 |
} |
|
1174 |
else |
|
1175 |
{ |
|
1176 |
/* Redirect STDOUT to file */ |
|
1177 |
if (dup2(output_fd, STDOUT_FILENO) == -1) |
|
1178 |
{ |
|
1179 |
close(output_fd); |
|
1180 |
fprintf(stderr, "Cannot redirect STDOUT to file %s\n", filename); |
|
1181 |
} |
|
1182 |
} |
|
1183 |
} |
|
1184 | ||
1185 |
/** |
|
1186 | 1154 |
* Main function which allows both password and P2J server-style authentication. |
1187 | 1155 |
* <p> |
1188 | 1156 |
* For P2J server-style authentiation, the following files need to exist in current directory: |
... | ... | |
1335 | 1303 |
if ((strcmp("-O", argv[i]) == 0) && (++i < argc)) |
1336 | 1304 |
{ |
1337 | 1305 |
strcpy(output_file_name, argv[i]); |
1306 |
output_to_file_opt_found = 1; |
|
1338 | 1307 |
} |
1339 | 1308 |
} |
1340 | 1309 |
src/native/winspawn.c 2023-01-27 13:45:24 +0000 | ||
---|---|---|
132 | 132 | |
133 | 133 |
unsigned char key1[KEY_SIZE + 1], key2[KEY_SIZE + 1], key3[KEY_SIZE + 1]; |
134 | 134 | |
135 |
/* STDOUT redirection flag. Default NO redirection */ |
|
136 |
int stdoutRedirect = 0; |
|
135 |
int outputToFileOption = 0; |
|
137 | 136 |
WCHAR szOutputFile[MAX_SIZE] = L""; |
138 | 137 | |
139 | 138 |
WCHAR szUserProfile[MAX_SIZE] = L""; |
... | ... | |
510 | 509 |
} |
511 | 510 | |
512 | 511 |
/** |
513 |
* Redirect STDOUT to an output file. |
|
514 |
* |
|
515 |
* @param szWorkingDir |
|
516 |
* Working directory. |
|
517 |
* @param szOutputFile |
|
518 |
* The name of the file where the STDOUT is redirected. |
|
519 |
*/ |
|
520 |
void stdout_redirect(LPWSTR szWorkingDir, LPWSTR szOutputFile) |
|
521 |
{ |
|
522 |
HANDLE hFile; |
|
523 |
WCHAR pid[32]; |
|
524 |
|
|
525 |
/* Goto working directory */ |
|
526 |
if (!SetCurrentDirectoryW(szWorkingDir)) |
|
527 |
{ |
|
528 |
DisplayError(L"SetCurrentDirectoryW"); |
|
529 |
} |
|
530 |
|
|
531 |
/* convert pid to string */ |
|
532 |
swprintf(pid, sizeof(pid), L"%lu", GetCurrentProcessId()); |
|
533 |
|
|
534 |
/* replace %pid% placeholder */ |
|
535 |
LPWSTR szFileName = replace_str(szOutputFile, L"%pid%", pid); |
|
536 |
|
|
537 |
SECURITY_ATTRIBUTES sa; |
|
538 |
sa.nLength = sizeof(sa); |
|
539 |
sa.lpSecurityDescriptor = NULL; |
|
540 |
sa.bInheritHandle = TRUE; |
|
541 |
|
|
542 |
/* create file */ |
|
543 |
hFile = CreateFileW(szFileName, // file name |
|
544 |
FILE_APPEND_DATA, // open for writing |
|
545 |
FILE_SHARE_WRITE | FILE_SHARE_READ, // allow multiple readers |
|
546 |
&sa, // security |
|
547 |
OPEN_ALWAYS, // open or create |
|
548 |
FILE_ATTRIBUTE_NORMAL, // normal file |
|
549 |
NULL); // no template |
|
550 |
|
|
551 |
/* check for errors */ |
|
552 |
if (hFile == INVALID_HANDLE_VALUE) |
|
553 |
{ |
|
554 |
DisplayError(L"CreateFileW"); |
|
555 |
} |
|
556 |
else |
|
557 |
{ |
|
558 |
/* redirect */ |
|
559 |
si.hStdOutput = hFile; |
|
560 |
si.dwFlags |= STARTF_USESTDHANDLES; |
|
561 |
} |
|
562 |
} |
|
563 | ||
564 |
/** |
|
565 | 512 |
* Spawn a child process on the current logon account. |
566 | 513 |
* |
567 | 514 |
* @param szWorkingDir |
... | ... | |
579 | 526 |
si.wShowWindow = SW_HIDE; |
580 | 527 |
// since Windows Vista we have to specify desktop session explicitly here |
581 | 528 |
si.lpDesktop = desktopDefault; |
582 | ||
583 |
/* Redirect STDOUT if required */ |
|
584 |
if (stdoutRedirect) |
|
585 |
{ |
|
586 |
stdout_redirect(szWorkingDir, szOutputFile); |
|
587 |
} |
|
588 | 529 |
|
589 | 530 |
if (!CreateProcessW(NULL, // application name |
590 | 531 |
szCommand, // command line |
... | ... | |
681 | 622 |
} |
682 | 623 |
szWorkingDir = szUserProfile; |
683 | 624 |
} |
684 |
|
|
685 |
/* Redirect STDOUT if required */ |
|
686 |
if (stdoutRedirect) |
|
687 |
{ |
|
688 |
stdout_redirect(szWorkingDir, szOutputFile); |
|
689 |
} |
|
690 | 625 | |
691 | 626 |
if (extra_logging > 0) |
692 | 627 |
{ |
... | ... | |
916 | 851 |
arguments to be null-terminated. */ |
917 | 852 |
char **arguments = (char**) malloc((length + 2) * sizeof(char*)); |
918 | 853 |
arguments[0] = NULL; |
919 |
arguments[length + 1] = NULL; |
|
854 |
arguments[length + 1 + outputToFileOption] = NULL; |
|
855 |
|
|
856 |
if (outputToFileOption == 1) |
|
857 |
{ |
|
858 |
int len = strlen(szOutputFile) + 1; |
|
859 |
arguments[length + 1] = (char*) malloc(len * sizeof(char)); |
|
860 |
memset(arguments[length + 1], '\0', len); |
|
861 |
strcpy(arguments[length + 1], szOutputFile); |
|
862 |
} |
|
863 |
|
|
920 | 864 |
int debug_option = 0; |
921 | 865 |
char *dbg_level = NULL; |
922 | 866 |
|
... | ... | |
1121 | 1065 |
if ((wcscmp(L"-O", argv[i]) == 0) && (++i < argc)) |
1122 | 1066 |
{ |
1123 | 1067 |
wcscpy(szOutputFile, argv[i]); |
1124 |
stdoutRedirect = 1; // restored redirection mode
|
|
1068 |
outputToFileOption = 1;
|
|
1125 | 1069 |
} |
1126 | 1070 |
} |
1127 | 1071 |
|