Author: mladen.turk(a)jboss.com
Date: 2007-09-20 04:39:38 -0400 (Thu, 20 Sep 2007)
New Revision: 1034
Modified:
trunk/sight/java/org/jboss/sight/ServiceState.java
trunk/sight/native/include/arch/unix/sight_private.h
trunk/sight/native/os/linux/scm.c
trunk/sight/native/os/linux/service.c
Log:
Add Linux service implementation
Modified: trunk/sight/java/org/jboss/sight/ServiceState.java
===================================================================
--- trunk/sight/java/org/jboss/sight/ServiceState.java 2007-09-20 06:14:06 UTC (rev 1033)
+++ trunk/sight/java/org/jboss/sight/ServiceState.java 2007-09-20 08:39:38 UTC (rev 1034)
@@ -64,7 +64,11 @@
/**
* The service is paused.
*/
- PAUSED( 7);
+ PAUSED( 7),
+ /**
+ * The service is disabled.
+ */
+ DISABLED( 8);
private int value;
private ServiceState(int v)
Modified: trunk/sight/native/include/arch/unix/sight_private.h
===================================================================
--- trunk/sight/native/include/arch/unix/sight_private.h 2007-09-20 06:14:06 UTC (rev
1033)
+++ trunk/sight/native/include/arch/unix/sight_private.h 2007-09-20 08:39:38 UTC (rev
1034)
@@ -61,6 +61,21 @@
#define SIGHT_PLATFORM_DECLARE(RT, CL, FN) \
JNIEXPORT RT JNICALL Java_org_jboss_sight_platform_unix_##CL##_##FN
+typedef struct scm_instance_t {
+ sight_arr_t *services;
+ const char *flavor; /* Linux flavor */
+ const char *idpath; /* Path of the init.d scripts */
+ const char *rlpath; /* Path or the rc0.d ... rc6.d scripts */
+ int what;
+} scm_instance_t;
+
+/* ServiceState status */
+#define SIGHT_SS_UNKNOWN 0
+#define SIGHT_SS_STOPPED 1
+#define SIGHT_SS_RUNNING 4
+#define SIGHT_SS_PAUSED 7
+#define SIGHT_SS_DISABLED 8
+
/**
* IANA Network adapter types
*/
Modified: trunk/sight/native/os/linux/scm.c
===================================================================
--- trunk/sight/native/os/linux/scm.c 2007-09-20 06:14:06 UTC (rev 1033)
+++ trunk/sight/native/os/linux/scm.c 2007-09-20 08:39:38 UTC (rev 1034)
@@ -35,32 +35,167 @@
#include "sight_types.h"
#include "sight_private.h"
+static const struct {
+ const char *flavor; /* Linux flavor */
+ const char *idpath; /* Path of the init.d scripts */
+ const char *rlpath; /* Format or the rc0.d ... rc6.d scripts */
+ int rlevel; /* Default run level */
+} scm_paths[] = {
+ { "redhat",
+ "/etc/rc.d/init.d/",
+ "/etc/rc.d/rc%d.d/",
+ 5
+ },
+ { "debian",
+ "/etc/init.d/",
+ "/etc/rc.d/rc%d.d/",
+ 5
+ },
+ { NULL,
+ NULL,
+ NULL,
+ 0
+ }
+};
+
+static void scm_cleanup(int mode, sight_object_t *no)
+{
+ if (no && no->native) {
+ scm_instance_t *scm = (scm_instance_t *)no->native;
+ if (scm->services)
+ sight_arr_free(scm->services);
+ free(scm);
+ no->native = NULL;
+ }
+}
+
+
SIGHT_EXPORT_DECLARE(jint, ServiceControlManager, open0)(SIGHT_STDARGS,
jlong instance,
jstring database,
jint mode)
{
- UNREFERENCED_STDARGS;
- UNREFERENCED(instance);
+ int i = 0;
+ DIR *sd = NULL;
+ scm_instance_t *si;
+ sight_object_t *no = J2P(instance, sight_object_t *);
+
+ UNREFERENCED_O;
UNREFERENCED(database);
UNREFERENCED(mode);
- return APR_ENOTIMPL;
+
+ if (!no || !no->pool) {
+ return APR_EINVAL;
+ }
+ if (no->native)
+ scm_cleanup(0, no);
+ if (!(si = (scm_instance_t *)sight_calloc(_E,
+ sizeof(scm_instance_t),
+ THROW_FMARK))) {
+ return apr_get_os_error();
+ }
+ no->native = si;
+ while (scm_paths[i].flavor) {
+ if ((sd = opendir(scm_paths[i].idpath))) {
+ si->flavor = scm_paths[i].flavor;
+ si->idpath = scm_paths[i].idpath;
+ si->rlpath = scm_paths[i].rlpath;
+ si->what = scm_paths[i].rlevel;
+ if (!(si->services = sight_arr_new(16))) {
+ apr_status_t rv = apr_get_os_error();
+ scm_cleanup(0, no);
+ return rv;
+ }
+ break;
+ }
+ i++;
+ }
+ if (sd) {
+ struct dirent *sent, sbuf;
+ while (!readdir_r(sd, &sbuf, &sent)) {
+ char sname[PATH_MAX];
+ struct stat sb;
+ if (!sent)
+ break;
+ strcpy(sname, si->idpath);
+ strcat(sname, sent->d_name);
+ if (stat(sname, &sb) < 0)
+ continue;
+ if (!S_ISREG(sb.st_mode))
+ continue;
+ if (!(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ continue;
+ sight_arr_add(si->services, sent->d_name);
+ }
+ closedir(sd);
+ no->clean = scm_cleanup;
+ return APR_SUCCESS;
+ }
+ else {
+ apr_status_t rv = apr_get_os_error();
+ scm_cleanup(0, no);
+ return rv;
+ }
}
SIGHT_EXPORT_DECLARE(void, ServiceControlManager, close0)(SIGHT_STDARGS,
jlong instance)
{
+ sight_object_t *no = J2P(instance, sight_object_t *);
+
UNREFERENCED_STDARGS;
- UNREFERENCED(instance);
+
+ if (no) {
+ scm_cleanup(0, no);
+ no->clean = NULL;
+ }
}
SIGHT_EXPORT_DECLARE(jobjectArray, ServiceControlManager,
enum0)(SIGHT_STDARGS, jlong instance,
jint drivers, jint what)
{
- UNREFERENCED_STDARGS;
- UNREFERENCED(instance);
- UNREFERENCED(drivers);
- UNREFERENCED(what);
- return NULL;
+ sight_object_t *no = J2P(instance, sight_object_t *);
+ scm_instance_t *si;
+ jobjectArray ea = NULL;
+ jsize cnt = 0;
+ jint idx = 0;
+
+ UNREFERENCED_O;
+ if (!no || !no->pool || !no->native) {
+ return NULL;
+ }
+ if (drivers) {
+ /* There are no drivers on linux ?
+ * Perhaps we should have here the kernel modules
+ */
+ return NULL;
+ }
+ si = (scm_instance_t *)no->native;
+ if (what > 0)
+ si->what = what;
+ if (si->services && si->services->siz) {
+ jint i;
+ /* TODO: Calculate size according to the flags */
+ cnt = si->services->siz;
+ ea = sight_new_cc_array(_E, SIGHT_CC_STRING, cnt);
+ if (!ea || (*_E)->ExceptionCheck(_E)) {
+ ea = NULL;
+ goto cleanup;
+ }
+ for (i = 0; i < cnt; i++) {
+ jstring s = (*_E)->NewStringUTF(_E, si->services->arr[i]);
+ if (s)
+ (*_E)->SetObjectArrayElement(_E, ea, idx++, s);
+ else
+ break;
+ if ((*_E)->ExceptionCheck(_E)) {
+ ea = NULL;
+ break;
+ }
+ (*_E)->DeleteLocalRef(_E, s);
+ }
+ }
+cleanup:
+ return ea;
}
Modified: trunk/sight/native/os/linux/service.c
===================================================================
--- trunk/sight/native/os/linux/service.c 2007-09-20 06:14:06 UTC (rev 1033)
+++ trunk/sight/native/os/linux/service.c 2007-09-20 08:39:38 UTC (rev 1034)
@@ -138,13 +138,61 @@
jstring name,
jint access)
{
- UNREFERENCED_STDARGS;
- UNREFERENCED(thiz);
- UNREFERENCED(instance);
- UNREFERENCED(scm);
- UNREFERENCED(name);
+ sight_object_t *no = J2P(instance, sight_object_t *);
+ sight_object_t *ns = J2P(scm, sight_object_t *);
+ scm_instance_t *si;
+ SIGHT_ALLOC_CSTRING(name);
+ int rc = 0;
+ char rlpath[PATH_MAX];
+ DIR *rd = NULL;
+
+
+ UNREFERENCED_O;
UNREFERENCED(access);
- return APR_ENOTIMPL;
+
+ if (!no || !no->pool) {
+ SIGHT_FREE_CSTRING(name);
+ return APR_EINVAL;
+ }
+ if (!ns || !ns->native) {
+ SIGHT_FREE_CSTRING(name);
+ return APR_EINVAL;
+ }
+ si = (scm_instance_t *)ns->native;
+ sprintf(rlpath, si->rlpath, si->what);
+ if ((rd = opendir(rlpath))) {
+ struct dirent *sent, sbuf;
+ int found = 0;
+ while (!readdir_r(rd, &sbuf, &sent)) {
+ char sname[PATH_MAX];
+ char smatch[PATH_MAX];
+ struct stat sb;
+ if (!sent)
+ break;
+ strcpy(sname, rlpath);
+ strcat(sname, sent->d_name);
+ strcpy(smatch, "*/S??");
+ strcat(smatch, J2S(name));
+ /* Match the SnnName */
+ if (!sight_wmatch(sname, smatch)) {
+ SET_IFIELD_S(0001, thiz, sname);
+ SET_IFIELD_S(0003, thiz, sent->d_name);
+ SET_IFIELD_S(0004, thiz, sent->d_name);
+ found = 1;
+ break;
+ }
+ }
+ closedir(rd);
+ if (found) {
+ /* Populate the fields */
+ CALL_METHOD1(0000, thiz, SIGHT_SS_UNKNOWN);
+ }
+ else {
+ CALL_METHOD1(0000, thiz, SIGHT_SS_DISABLED);
+ }
+ }
+ SIGHT_FREE_CSTRING(name);
+ return APR_FROM_OS_ERROR(rc);
}
SIGHT_EXPORT_DECLARE(jint, Service, ctrl0)(SIGHT_STDARGS,