You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by mt...@apache.org on 2003/10/04 11:32:28 UTC
cvs commit: jakarta-commons/daemon/src/native/nt/procrun procgui.c procrun.c
mturk 2003/10/04 02:32:28
Modified: daemon/src/native/nt/procrun procgui.c procrun.c
Log:
Comment the code a bit.
Can some native speaker check the spelling and grammar?
Revision Changes Path
1.8 +62 -2 jakarta-commons/daemon/src/native/nt/procrun/procgui.c
Index: procgui.c
===================================================================
RCS file: /home/cvs/jakarta-commons/daemon/src/native/nt/procrun/procgui.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- procgui.c 2 Oct 2003 07:21:29 -0000 1.7
+++ procgui.c 4 Oct 2003 09:32:28 -0000 1.8
@@ -156,6 +156,10 @@
INT_PTR ac_show_properties(HWND owner);
+/* Create the list view using ac_columns struct.
+ * You may change the ac_columns to a different layout
+ * (see the tomcat.c for example)
+ */
static void lv_create_view(HWND hdlg, LPRECT pr, LPRECT pw)
{
LV_COLUMN lvc;
@@ -205,6 +209,8 @@
/*
* Find the first occurrence of find in s.
+ * This is the case insesitive version of strstr
+ * that the MSVCRT is missing
*/
static char *
stristr(register const char *s, register const char *find)
@@ -225,6 +231,10 @@
return ((char *)s);
}
+/* Parse the stdout messages and try to figure out what it is about.
+ * Display the icon in the list view acording to that message.
+ * If param from is nonzero (from stderr), display the error icon.
+ */
void parse_list_string(const char *str, int from)
{
int row = 0x7FFFFFFF;
@@ -267,6 +277,9 @@
lv_parse_cb_t lv_parser = parse_list_string;
+/* Try icon helper
+ * Add/Change/Delete icon from the windows try.
+ */
void ac_show_try_icon(HWND hwnd, DWORD message, const char *tip, int stop)
{
@@ -294,6 +307,10 @@
Shell_NotifyIcon(message, &nid);
}
+/* Main console dialog print function
+ * The str comes either from redirected child's stdout
+ * or stderr pipe.
+ */
void ac_add_list_string(const char *str, int len, int from)
{
static int nqueue = 0;
@@ -312,7 +329,9 @@
else
SendMessage(ac_splist_hwnd, LB_INSERTSTRING, 0, (LPARAM)str);
}
-
+ /* Ensure that we dont have more the MAX_LISTCOUNT
+ * in the queue
+ */
if (nqueue > MAX_LISTCOUNT - 1) {
free(ac_stdout_lines[0]);
/* TODO: improve performance */
@@ -320,13 +339,19 @@
ac_stdout_lines[i - 1] = ac_stdout_lines[i];
--nqueue;
}
+ /* add the string to the queue */
ac_stdout_lines[nqueue++] = strdup(str);
nlen = max(nlen, len);
}
+ /* If there is no window or the queue is empty return */
if (!ac_list_hwnd || !nqueue)
return;
+ /* Ok. We have the window open and something in the queue.
+ * Flush that to the screen.
+ */
if (ac_use_lview) {
for (i = 0; i < nqueue; i++) {
+ /* Call the list view callback parser */
(*lv_parser)(ac_stdout_lines[i], from);
if (litems++ > MAX_LIST_ITEMS)
ListView_DeleteItem(ac_list_hwnd, 0);
@@ -334,8 +359,12 @@
}
else
{
+ /* Flush all the lines from the queue */
for (i = 0; i < nqueue; i++) {
ListBox_AddString(ac_list_hwnd, ac_stdout_lines[i]);
+ /* Ensure no more then MAX_LIST_ITEMS are maintained.
+ * This ensures that we dont waste to much system resources.
+ */
if (litems++ > MAX_LIST_ITEMS)
ListBox_DeleteString(ac_list_hwnd, 0);
@@ -346,6 +375,7 @@
(WPARAM) 10 * olen, (LPARAM) 0);
}
}
+ /* Remove all the lines from the queue */
for (i = 0; i < nqueue; i++) {
free(ac_stdout_lines[i]);
ac_stdout_lines[i] = NULL;
@@ -353,6 +383,8 @@
nqueue = 0;
}
+/* Add the item to the Try popup menu
+ */
static void ac_append_menu_item(HMENU menu, UINT menu_id, char *name, int isdef, int enabled)
{
MENUITEMINFO mii;
@@ -374,6 +406,8 @@
InsertMenuItem(menu, menu_id, FALSE, &mii);
}
+/* Show the Try popup menu
+ */
static void ac_show_try_menu(HWND hwnd)
{
HMENU menu;
@@ -403,6 +437,9 @@
}
}
+/* Sopy selected items from the console dialog
+ * to the windows clipboard
+ */
static int ac_copy_to_clipboard()
{
HGLOBAL hglbcopy = NULL;
@@ -469,6 +506,7 @@
return 0;
}
+/* Center the hwnd on the user desktop */
void ac_center_window(HWND hwnd)
{
RECT rc, rw;
@@ -647,6 +685,10 @@
return FALSE;
}
+/* Browse dialog.
+ * Brose either for file or folder.
+ * TODO: add some file filters.
+ */
int ac_browse_for_dialog(HWND hwnd, char *str, size_t len, int files)
{
int rv = 0;
@@ -685,6 +727,8 @@
}
+/* Service option dialogs
+ */
void CALLBACK PropSheetCallback(HWND hwndPropSheet, UINT uMsg, LPARAM lParam)
{
switch(uMsg) {
@@ -1085,7 +1129,9 @@
return FALSE;
}
-
+/* main (invisible) window procedure
+ *
+ */
LRESULT CALLBACK ac_main_wnd_proc(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{
@@ -1220,6 +1266,9 @@
}
+/* Main GUI application thread
+ * launched from procrun_main.
+ */
DWORD WINAPI gui_thread(LPVOID param)
{
DWORD rv = 0;
@@ -1246,6 +1295,11 @@
else
ac_cmdname = env->m->service.name;
+ /* Ensure that only one instance of a service is running
+ * TODO: Allow the //ES// and //MS// to run withouth that
+ * restriction, but reather use that mutex to signal
+ * the //GT// of a params change.
+ */
mutex = CreateMutex(NULL, FALSE, cmutex);
if ((mutex == NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) {
char msg[2048];
@@ -1260,6 +1314,10 @@
}
#if defined(PROCRUN_EXTENDED)
+ /* Init all the extended properties
+ * like splash, listview, etc..
+ *
+ */
acx_init_extended();
#endif
ac_main_hwnd = ac_create_main_window(ac_instance, cname,
@@ -1269,6 +1327,7 @@
if (ac_main_hwnd) {
if (ac_use_try)
ac_taskbar_created = RegisterWindowMessage("TaskbarCreated");
+ /* Main message loop */
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
@@ -1277,6 +1336,7 @@
if (mutex)
CloseHandle(mutex);
ac_main_hwnd = NULL;
+ /* Signal to procrun_main we are done */
SetEvent(env->m->events[0]);
return rv;
}
1.8 +198 -16 jakarta-commons/daemon/src/native/nt/procrun/procrun.c
Index: procrun.c
===================================================================
RCS file: /home/cvs/jakarta-commons/daemon/src/native/nt/procrun/procrun.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- procrun.c 2 Oct 2003 07:22:16 -0000 1.7
+++ procrun.c 4 Oct 2003 09:32:28 -0000 1.8
@@ -170,6 +170,11 @@
#define DBPRINTF2(v1, v2, v3)
#endif
+/* Create the memory pool.
+ * Memory pool is fixed size (PROC_POOL_SIZE -> 128 by default)
+ * It ensures that all the memory and HANDELS gets freed
+ * when the procrun exits
+ */
pool_t *pool_create()
{
pool_t *pool = malloc(sizeof(pool_t));
@@ -182,6 +187,11 @@
return pool;
}
+/* Destroy the memory pool
+ * each pool slot can have allocated memory block
+ * and/or associated windows HANDLE that can be
+ * release with CloseHandle.
+ */
int pool_destroy(pool_t *pool)
{
int i = 0;
@@ -198,6 +208,9 @@
return i;
}
+/* Allocation functions
+ * They doesn't check for overflow
+ */
static void *pool_alloc(pool_t *pool, size_t size)
{
void *m = malloc(size);
@@ -228,6 +241,10 @@
return s;
}
+/* Attach the Handle to the pool
+ * The handle will be released on pool_destroy
+ * using CloseHandle API call
+ */
static void *pool_handle(pool_t *pool, HANDLE h)
{
EnterCriticalSection(&pool->lock);
@@ -249,6 +266,13 @@
return CloseHandle(h);
}
+/* Very simple encryption for hiding password
+ * they can be easily decrypted cause the key
+ * is hadcoded (100) in the code.
+ * It can be easily cracked if someone finds that needed.
+ * XXX: The solution is to either use the CryproAPI
+ * or our own account management.
+ */
static void simple_encrypt(int seed, const char *str, unsigned char bytes[256])
{
int i;
@@ -274,15 +298,19 @@
strcpy(str, sc);
}
-static void test_enc()
-{
- unsigned char b[256];
- char op[32];
- simple_encrypt(100, "test encryption", b);
- simple_decrypt(100, op, b);
- DBPRINTF1("ENC %s", op);
-}
-
+/* Injects the 'ExitProcess' to the child
+ * The function tries to kill the child process
+ * without using 'hard' mathods like TerminateChild.
+ * At first it sends the CTRL+C and CTRL+BREAK to the
+ * child process. If that fails (the child doesn't exit)
+ * it creates the remote thread in the address space of
+ * the child process, and calls the ExitProcess function,
+ * inside the child process.
+ * Finaly it calls the TerminateProcess all of the above
+ * fails.
+ * Well designed console clients usually exits on closing
+ * stdin stream, so this function not be called in most cases.
+ */
static void inject_exitprocess(PROCESS_INFORMATION *child)
{
PFNCREATERTHRD pfn_CreateRemoteThread;
@@ -368,6 +396,10 @@
return _stricoll(*((char **)arg1),*((char **)arg2));
}
+/* Merge two char arrays and make
+ * zero separated, double-zero terminated
+ * string
+ */
static char * merge_arrays(char **one, char **two, process_t *proc)
{
int len = 0, n, cnt = 0;
@@ -394,6 +426,11 @@
return envp;
}
+/* Make the environment string
+ * for the child process.
+ * The original environment of the calling process
+ * is merged with the current environment.
+ */
static char * make_environment(char **envarr, char **envorg, process_t *proc)
{
int len = 0, n, cnt = 0;
@@ -446,6 +483,12 @@
return envp;
}
+/* Make the character string array form
+ * zero separated, double-zero terminated
+ * strings. Those strings comes from some
+ * Windows api calls, like GetEnvironmentStrings
+ * This string format is also used in Registry (REG_MULTI_SZ)
+ */
static int make_array(const char *str, char **arr, int size, process_t *proc)
{
int i = 0;
@@ -464,6 +507,9 @@
return i;
}
+/* Simple string unqouting
+ * TODO: Handle multiqoutes.
+ */
static char *remove_quotes(char * string) {
char *p = string, *q = string;
while (*p) {
@@ -555,6 +601,9 @@
return mode;
}
+/* Print some statistics about the current process
+ *
+ */
static void debug_process(int argc, char **argv, process_t *p)
{
DBPRINTF1("DUMPING %s\n", argv[0]);
@@ -579,6 +628,9 @@
DBPRINTF0("DONE...\n");
}
+/* Add the environment variable 'name=value'
+ * to the environment that will be passed to the child process.
+ */
static int procrun_addenv(char *name, char *value, int val, process_t *proc)
{
int i;
@@ -606,6 +658,11 @@
return -1;
}
+/* Read the environment.
+ * This function reads the procrun defined environment
+ * variables passed from the calling process,
+ * if the calling process is a procrun instance.
+ */
static int procrun_readenv(process_t *proc, char **envp)
{
int i, rv = 0;
@@ -669,6 +726,10 @@
return rv;
}
+/* Find the default jvm.dll
+ * The function scans through registry and finds
+ * default JRE jvm.dll.
+ */
static char* procrun_guess_jvm(process_t *proc)
{
HKEY hkjs;
@@ -712,6 +773,11 @@
return pool_strdup(proc->pool, jvm);
}
+/* Find the java/javaw (depending on image)
+ * The function locates the JavaHome Registry entry
+ * and merges that path with the requested image
+ */
+
static char* procrun_guess_java(process_t *proc, const char *image)
{
HKEY hkjs;
@@ -757,6 +823,10 @@
return pool_strdup(proc->pool, jbin);
}
+/* Find the system JavaHome path.
+ * The "JAVA_HOME" environment variable
+ * gets procedance over registry settings
+ */
static char* procrun_guess_java_home(process_t *proc)
{
HKEY hkjs;
@@ -806,6 +876,9 @@
return pool_strdup(proc->pool, jbin);
}
+/* Read the service parameters from the registry
+ *
+ */
static int procrun_service_params(process_t *proc)
{
HKEY key;
@@ -1025,6 +1098,11 @@
return -1;
}
+/* Decide if we need the java
+ * Check the registry and decide how the java
+ * is going to be loaded.
+ * Using inprocess jvm.dll or as a child process running java.exe
+ */
static int procrun_load_jvm(process_t *proc, int mode)
{
int has_java = 0;
@@ -1145,6 +1223,10 @@
DBPRINTF0("JVM abort hook called\n");
}
+/* 'Standard' JNI functions
+ *
+ */
+
static JNIEnv *jni_attach(process_t *proc)
{
JNIEnv *env = NULL;
@@ -1177,6 +1259,10 @@
return (*jvm)->DetachCurrentThread(jvm);
}
+/* Destroy the jvm.
+ * This method stops the current jvm calling
+ * configured stop methods and destroys the loaded jvm.
+ */
static int procrun_destroy_jvm(process_t *proc, HANDLE jh)
{
JavaVM *jvm = proc->java.jvm;
@@ -1246,6 +1332,10 @@
return err;
}
+/* Initialize loaded jvm.dll
+ * Pass the startup options to the jvm,
+ * and regiter the start/top classes and methods
+ */
static int procrun_init_jvm(process_t *proc)
{
int jvm_version;
@@ -1370,7 +1460,10 @@
return -1;
}
-
+/* Thread that waits for child process to exit
+ * When the child process exits, it sets the
+ * event so that we can exit
+ */
DWORD WINAPI wait_thread(LPVOID param)
{
procrun_t *env = (procrun_t *)param;
@@ -1385,6 +1478,11 @@
return 0;
}
+/* Redirected stdout reader thread
+ * It reads char at a time and writes
+ * either to stdout handle (file or pipe)
+ * or calls the gui console printer function.
+ */
DWORD WINAPI stdout_thread(LPVOID param)
{
unsigned char ch;
@@ -1407,11 +1505,11 @@
n = 0;
}
else if (ch == '\t' && n < (MAX_PATH - 4)) {
- int i;
+ int i; /* replace the TAB with four spaces */
for (i = 0; i < 4; ++i)
buff[n++] = ' ';
}
- else if (ch != '\r')
+ else if (ch != '\r') /* skip the CR and BELL */
buff[n++] = ch;
else if (ch != '\b')
buff[n++] = ' ';
@@ -1426,10 +1524,19 @@
readed = 0;
}
}
+ /* The client has closed it side of a pipe
+ * meaning that he has finished
+ */
SetEvent(env->m->events[2]);
return 0;
}
+/* Redirected stderr reader thread
+ * It reads char at a time and writes
+ * either to stderr handle (file or pipe)
+ * or calls the gui console printer function.
+ */
+
DWORD WINAPI stderr_thread(LPVOID param)
{
unsigned char ch;
@@ -1475,6 +1582,9 @@
return 0;
}
+/* Created redirection pipes, and close the unused sides.
+ *
+ */
static int procrun_create_pipes(procrun_t *env)
{
SECURITY_ATTRIBUTES sa;
@@ -1561,6 +1671,9 @@
return 0;
}
+/* Write the specified file to the childs stdin.
+ * This function wraps 'child.exe <some_file'
+ */
static int procrun_write_stdin(procrun_t *env)
{
DWORD readed, written;
@@ -1587,6 +1700,9 @@
return 0;
}
+/* Make the command line for starting or stopping
+ * java process.
+ */
static char * set_command_line(procrun_t *env, char *program, int starting){
int i, j, len = strlen(env->m->argw) + 8192;
char *opts[64], *nargw;
@@ -1627,6 +1743,13 @@
return program;
}
+/* Main redirection function.
+ * Create the redirection pipes
+ * Make the child's environment
+ * Make the command line
+ * Logon as different user
+ * Create the child process
+ */
int procrun_redirect(char *program, char **envp, procrun_t *env, int starting)
{
STARTUPINFO si;
@@ -1667,6 +1790,7 @@
}
DBPRINTF2("RUN [%s] %s\n", program, env->m->argw);
if (env->m->service.account && env->m->service.password && starting) {
+ /* Run the child process under a different user account */
HANDLE user, token;
DBPRINTF2("RUNASUSER %s@%s\n", env->m->service.account, env->m->service.password);
if (!LogonUser(env->m->service.account,
@@ -1728,7 +1852,7 @@
return -1;
}
}
- DBPRINTF1("started java thread %08x",env->c->pinfo.hThread);
+ DBPRINTF1("started child thread %08x",env->c->pinfo.hThread);
if(starting) {
pool_handle(env->c->pool, env->c->pinfo.hThread);
pool_handle(env->c->pool, env->c->pinfo.hProcess);
@@ -1752,6 +1876,8 @@
return 0;
}
+/* Delete the value from the registry
+ */
static int del_service_param(process_t *proc, const char *name)
{
HKEY key;
@@ -1773,6 +1899,9 @@
}
+/* Update or create the value in the registry
+ *
+ */
static int set_service_param(process_t *proc, const char *name,
const char *value, int len, int service)
{
@@ -1821,7 +1950,7 @@
}
/*
- * Process the arguments.
+ * Process the arguments and fill the process_t stuct.
*/
static int process_args(process_t *proc, int argc, char **argv,
char **java, char *path)
@@ -2017,6 +2146,9 @@
proc->java.opts, l + 2, 0);
}
}
+
+/* Install the service
+ */
static int procrun_install_service(process_t *proc, int argc, char **argv)
{
SC_HANDLE service;
@@ -2146,6 +2278,9 @@
return 0;
}
+/* Update the service parameters
+ * This is the main parser for //US//
+ */
int procrun_update_service(process_t *proc, int argc, char **argv)
{
SC_HANDLE service;
@@ -2291,7 +2426,10 @@
return 0;
}
-
+/* Delete the service
+ * Removes the service form registry and SCM.
+ * Stop the service if running.
+ */
static int procrun_delete_service(process_t *proc)
{
SC_HANDLE service;
@@ -2534,6 +2672,8 @@
return TRUE;
}
+/* Report the service status to the SCM
+ */
int report_service_status(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint,
@@ -2567,6 +2707,8 @@
return fResult;
}
+/* Service controll handler
+ */
void WINAPI service_ctrl(DWORD dwCtrlCode)
{
switch (dwCtrlCode) {
@@ -2586,6 +2728,9 @@
NO_ERROR, 0, g_env->m);
}
+/* Console controll handler
+ *
+ */
BOOL WINAPI console_ctrl(DWORD dwCtrlType)
{
switch (dwCtrlType) {
@@ -2611,6 +2756,10 @@
return FALSE;
}
+/* Main JVM thread
+ * Like redirected process, the redirected JVM application
+ * is run in the separate thread.
+ */
DWORD WINAPI java_thread(LPVOID param)
{
DWORD rv;
@@ -2654,11 +2803,13 @@
if (g_env->m->java.dll) {
if (g_env->m->java.jbin == NULL) {
DWORD id;
+ /* Create the main JVM thread so we don't get blocked */
jh = CreateThread(NULL, 0, java_thread, g_env, 0, &id);
pool_handle(g_env->m->pool, jh);
rv = 0;
}
else {
+ /* Redirect java or javaw */
if ((rv = procrun_init_jvm(g_env->m)) == 0) {
rv = procrun_redirect(g_env->m->service.image,
g_env->m->envp, g_env, 1);
@@ -2701,7 +2852,8 @@
return rv;
}
-
+/* Procrun main function
+ */
int procrun_main(int argc, char **argv, char **envp, procrun_t *env)
{
int i, mode = 0;
@@ -2724,6 +2876,7 @@
}
DBPRINTF1("OS Version %d\n", g_is_windows_nt);
+ /* Set console handler to capture CTRL events */
SetConsoleCtrlHandler((PHANDLER_ROUTINE)console_ctrl, TRUE);
env->m->pool = pool_create();
env->c->pool = pool_create();
@@ -2792,6 +2945,8 @@
nenv += strlen(nenv)+1;
}
}
+ /* Create the four events that will cause us to exit
+ */
sprintf(event, "PROC_SHUTDOWN_EVENT%d", GetCurrentProcessId());
env->m->events[0] = CreateEvent(NULL, TRUE, FALSE, event);
sprintf(event, "PROC_EXITWAIT_EVENT%d", GetCurrentProcessId());
@@ -2809,12 +2964,18 @@
DBPRINTF1("Events %p\n", env->m->events[0]);
switch (mode) {
+ /* Standard run modes */
case PROCRUN_CMD_TEST_SERVICE:
#ifdef PROCRUN_WINAPP
+ /*
+ * GUIT: Display as Try application
+ * GUOD: Immediately popup console dialog wrapper
+ */
case PROCRUN_CMD_GUIT_SERVICE:
case PROCRUN_CMD_GUID_SERVICE:
{
DWORD gi;
+ /* This one if for about box */
LoadLibrary("riched32.dll");
CreateThread(NULL, 0, gui_thread, g_env, 0, &gi);
}
@@ -2830,11 +2991,14 @@
service_main(argc, argv);
break;
#ifdef PROCRUN_WINAPP
+ /* Display the service properties dialog
+ */
case PROCRUN_CMD_EDIT_SERVICE:
LoadLibrary("riched32.dll");
gui_thread(g_env);
break;
#endif
+ /* Management modes */
case PROCRUN_CMD_INSTALL_SERVICE:
if (g_is_windows_nt)
rv = procrun_install_service(env->m, argc, argv);
@@ -2881,6 +3045,7 @@
break;
#ifdef PROCRUN_WINAPP
case PROCRUN_CMD_GUID_PROCESS:
+ /* run as WIN32 application */
{
DWORD gi;
ac_use_try = 1;
@@ -3002,6 +3167,14 @@
return TRUE;
}
+/* DLL mode functions
+ * Ment to be used either from other programs
+ * or from installers
+ */
+
+/* Install the service.
+ * This is a wrapper for //IS//
+ */
__declspec(dllexport) void InstallService(const char *service_name,
const char *install,
const char *image_path,
@@ -3035,6 +3208,11 @@
g_env = NULL;
}
+/* Update the service.
+ * This is a wrapper for //US//
+ *
+ */
+
__declspec(dllexport) void UpdateService(const char *service_name,
const char *param,
const char *value)
@@ -3061,6 +3239,10 @@
free_environment(env);
g_env = NULL;
}
+
+/* Remove the service.
+ * This is a wrapper for //DS//
+ */
__declspec(dllexport) void RemoveService(const char *service_name)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org