summaryrefslogtreecommitdiffstats
path: root/www/orion
diff options
context:
space:
mode:
authorznerd <znerd@FreeBSD.org>2002-03-28 14:52:37 +0000
committerznerd <znerd@FreeBSD.org>2002-03-28 14:52:37 +0000
commita70e8f88eb63fbb102f347f9e69579f5e5f91b1c (patch)
tree337b81dafec81ade5e4d9c0b1472e770d475b45c /www/orion
parentfebdfcd765481846de3c10363cf6bb0bb81bbc79 (diff)
downloadFreeBSD-ports-a70e8f88eb63fbb102f347f9e69579f5e5f91b1c.zip
FreeBSD-ports-a70e8f88eb63fbb102f347f9e69579f5e5f91b1c.tar.gz
Using a C program instead of a shell script for controlling
the server, so that we can use set the effective UID of the control script. Redirecting stdout output from the startup script to /dev/null. Bumped PORTREVISION to 10.
Diffstat (limited to 'www/orion')
-rw-r--r--www/orion/Makefile10
-rw-r--r--www/orion/files/daemonctl.c366
-rw-r--r--www/orion/files/orion.sh4
-rw-r--r--www/orion/files/orionctl180
4 files changed, 375 insertions, 185 deletions
diff --git a/www/orion/Makefile b/www/orion/Makefile
index 5c55b9d..6a7df32 100644
--- a/www/orion/Makefile
+++ b/www/orion/Makefile
@@ -7,7 +7,7 @@
PORTNAME= orion
PORTVERSION= 1.5.2
-PORTREVISION= 9
+PORTREVISION= 10
CATEGORIES= www java
MASTER_SITES= http://www.orionserver.com/distributions/ \
http://www.atlassian.com/software/orion/downloads/ \
@@ -42,7 +42,7 @@ STDOUT_LOG= ${LOG_DIR}/stdout.log
STDERR_LOG= ${LOG_DIR}/stderr.log
AUTO_START?= NO
PID_FILE= /var/run/${APP_SHORTNAME}.pid
-REPLACE_FILES= ${FILESDIR}/${CONTROL_SCRIPT_NAME} \
+REPLACE_FILES= ${FILESDIR}/daemonctl.c \
${FILESDIR}/${CONTROL_SCRIPT_NAME}.1 \
${FILESDIR}/${STARTUP_SCRIPT_NAME}
@@ -97,7 +97,9 @@ do-install:
-e "/%%CONTROL_SCRIPT%%/s//${CONTROL_SCRIPT:S/\//\\\//g}/" \
-e "/%%CONTROL_SCRIPT_NAME%%/s//${CONTROL_SCRIPT_NAME}/" \
-e "/%%GROUP%%/s//${GROUP}/" \
+ -e "/%%JAVA_CMD%%/s//bin\/java/" \
-e "/%%JAVA_HOME%%/s//${JAVA_HOME:S/\//\\\//g}/" \
+ -e "/%%JAR_FILE%%/s//${APP_SHORTNAME}.jar/" \
-e "/%%LOG_DIR%%/s//${LOG_DIR:S/\//\\\//g}/" \
-e "/%%PORTNAME%%/s//${PORTNAME}/" \
-e "/%%PORTVERSION%%/s//${PORTVERSION}/" \
@@ -118,8 +120,10 @@ do-install:
@${ECHO_CMD} " [ DONE ]"
.endif
- @${ECHO_CMD} -n ">> Installing control script..."
+ @${ECHO_CMD} -n ">> Compiling and installing control script..."
+ @cd ${WRKDIR} && ${CC} -ansi -o ${CONTROL_SCRIPT_NAME} daemonctl.c
@${CP} ${WRKDIR}/${CONTROL_SCRIPT_NAME} ${CONTROL_SCRIPT}
+ @${CHOWN} ${USER}:${GROUP} ${CONTROL_SCRIPT}
@${CHMOD} 6754 ${CONTROL_SCRIPT}
@${ECHO_CMD} " [ DONE ]"
diff --git a/www/orion/files/daemonctl.c b/www/orion/files/daemonctl.c
new file mode 100644
index 0000000..d074f72
--- /dev/null
+++ b/www/orion/files/daemonctl.c
@@ -0,0 +1,366 @@
+/*
+ * -*- mode: Fundamental; tab-width: 4; -*-
+ * ex:ts=4
+ *
+ * Daemon control program.
+ *
+ * $FreeBSD$
+ */
+
+#include <assert.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#define MAX_FILE_SIZE 32
+
+#define ERR_ILLEGAL_ARGUMENT 1
+#define ERR_PID_FILE_NOT_FOUND 2
+#define ERR_PID_FILE_TOO_LARGE 3
+#define ERR_PID_FILE_CONTAINS_ILLEGAL_CHAR 4
+#define ERR_KILL_FAILED 5
+#define ERR_ALREADY_RUNNING 6
+#define ERR_NOT_RUNNING 7
+#define ERR_CHDIR_TO_APP_HOME 8
+#define ERR_STDOUT_LOGFILE_OPEN 9
+#define ERR_STDERR_LOGFILE_OPEN 10
+#define ERR_FORK_FAILED 11
+
+#define private static
+
+private void printUsage(void);
+private int openPIDFile(void);
+private int readPID(int);
+private void writePID(int file, int pid);
+private void start(void);
+private void stop(void);
+private void restart(void);
+
+
+/**
+ * Main function. This function is called when this program is executed.
+ *
+ * @param argc
+ * the number of arguments plus one, so always greater than 0.
+ *
+ * @param argv
+ * the arguments in an array of character pointers, where the last argument
+ * element is followed by a NULL element.
+ */
+int main(int argc, char *argv[]) {
+
+ /* Declare variables, like all other good ANSI C programs do :) */
+ char *argument;
+
+ /* Parse the arguments */
+ if (argc != 2) {
+ printUsage();
+ return 0;
+ }
+
+ argument = argv[1];
+ if (strcmp("start", argument) == 0) {
+ start();
+ } else if (strcmp("stop", argument) == 0) {
+ stop();
+ } else if (strcmp("restart", argument) == 0) {
+ restart();
+ } else {
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Illegal argument \"%s\".\n", argument);
+ printUsage();
+ exit(ERR_ILLEGAL_ARGUMENT);
+ }
+
+ return 0;
+}
+
+
+/**
+ * Prints usage information to stdout.
+ */
+void printUsage(void) {
+ printf("Usage: %%CONTROL_SCRIPT_NAME%% [ start | stop | restart ]\n");
+}
+
+
+/**
+ * Attempts to open the PID file. If that file is successfully opened, then
+ * the file handle (an int) will be returned.
+ *
+ * @return
+ * the file handle.
+ */
+int openPIDFile(void) {
+
+ int file;
+
+ /* Attempt to open the PID file */
+ printf(">> Opening PID file (%%PID_FILE%%)...");
+ file = open("%%PID_FILE%%", O_RDWR);
+ if (file < 0) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to open %%PID_FILE%% for reading and writing: ");
+ perror(NULL);
+ exit(ERR_PID_FILE_NOT_FOUND);
+ }
+ printf(" [ DONE ]\n");
+
+ return file;
+}
+
+
+/**
+ * Reads a PID from the specified file. The file is identified by a file
+ * handle.
+ *
+ * @param file
+ * the file handle.
+ *
+ * @return
+ * the PID, or -1 if the file was empty.
+ */
+int readPID(int file) {
+
+ char *buffer;
+ int hadNewline = 0;
+ unsigned int count;
+ unsigned int i;
+ int pid;
+
+ /* Read the PID file contents */
+ printf(">> Reading PID file...");
+ buffer = (char *) malloc((MAX_FILE_SIZE + 1) * sizeof(char));
+ count = read(file, buffer, MAX_FILE_SIZE + 1);
+ if (count > MAX_FILE_SIZE) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: The file %%PID_FILE%% contains more than %d bytes.\n", MAX_FILE_SIZE);
+ exit(ERR_PID_FILE_TOO_LARGE);
+ }
+
+ /* Convert the bytes to a number */
+ pid = 0;
+ for (i=0; i<count; i++) {
+ char c = buffer[i];
+ if (c >= '0' && c <= '9') {
+ char digit = c - '0';
+ pid *= 10;
+ pid += digit;
+ } else if (i == (count - 1) && c == '\n') {
+ /* XXX: Ignore a newline at the end of the file */
+ hadNewline = 1;
+ } else {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: The file %%PID_FILE%% contains an illegal character (%d) at position %d.\n", c, i);
+ exit(ERR_PID_FILE_CONTAINS_ILLEGAL_CHAR);
+ }
+ }
+ printf(" [ DONE ]\n");
+
+ if (count == 0 || (count == 1 && hadNewline == 1)) {
+ return -1;
+ }
+
+ return pid;
+}
+
+
+/**
+ * Writes a process ID to the specified file. The file is identified by a file
+ * handle.
+ *
+ * @param file
+ * the file handle, always greater than 0.
+ *
+ * @param pid
+ * the PID to store, always greater than 0.
+ */
+void writePID(int file, int pid) {
+
+ char *buffer;
+ int nbytes;
+
+ /* Check preconditions */
+ assert(file > 0);
+ assert(pid > 0);
+
+ printf(">> Writing PID file...");
+
+ lseek(file, 0, SEEK_SET);
+ ftruncate(file, 0);
+ nbytes = asprintf(&buffer, "%d\n", pid);
+ write(file, buffer, nbytes);
+ printf(" [ DONE ]\n");
+}
+
+
+/**
+ * Kills the process identified by the specified ID.
+ *
+ * @param pid
+ * the process id, greater than 0.
+ */
+void killProcess(int pid) {
+
+ int result;
+
+ assert(pid > 0);
+
+ printf(">> Killing process %d...", pid);
+ result = kill(pid, SIGTERM);
+ if (result < 0) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to kill process %d: ", pid);
+ perror(NULL);
+ exit(ERR_KILL_FAILED);
+ }
+
+ printf(" [ DONE ]\n");
+}
+
+
+/**
+ * Starts the daemon.
+ */
+void start(void) {
+
+ int file;
+ int pid;
+ int result;
+ int stdoutLogFile;
+ int stderrLogFile;
+
+ /* Open and read the PID file */
+ file = openPIDFile();
+ pid = readPID(file);
+
+ printf(">> Checking that %%APP_TITLE%% is not already running...");
+ if (pid != -1) {
+
+ /* Check if the process actually exists */
+ result = kill(pid, 0);
+ if (result == 0 || errno != ESRCH) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: %%APP_TITLE%% is already running, PID is %d.\n", pid);
+ exit(ERR_ALREADY_RUNNING);
+ }
+ }
+
+ printf(" [ DONE ]\n");
+
+ /* XXX: printf(">> Checking for Java VM..."); */
+
+ printf(">> Starting %%APP_TITLE%%...");
+
+ /* Change directory */
+ result = chdir("%%APP_HOME%%");
+ if (result < 0) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to access directory %%APP_HOME%%: ");
+ perror(NULL);
+ exit(ERR_CHDIR_TO_APP_HOME);
+ }
+
+ /* Open the stdout log file */
+ stdoutLogFile = open("%%STDOUT_LOG%%", O_WRONLY);
+ if (stdoutLogFile < 0) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to open %%STDOUT_LOG%% for writing: ");
+ perror(NULL);
+ exit(ERR_STDOUT_LOGFILE_OPEN);
+ }
+ lseek(stdoutLogFile, 0, SEEK_END);
+
+ /* Open the stderr log file */
+ stderrLogFile = open("%%STDERR_LOG%%", O_WRONLY);
+ if (stderrLogFile < 0) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to open %%STDERR_LOG%% for writing: ");
+ perror(NULL);
+ exit(ERR_STDERR_LOGFILE_OPEN);
+ }
+ lseek(stderrLogFile, 0, SEEK_END);
+
+ /* Split this process in two */
+ pid = fork();
+ if (pid == -1) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to fork: ");
+ perror(NULL);
+ exit(ERR_FORK_FAILED);
+ }
+
+ if (pid == 0) {
+
+ /* Redirect stdout to log file */
+ dup2(stdoutLogFile, STDOUT_FILENO);
+
+ /* Redirect stderr to log file */
+ dup2(stderrLogFile, STDERR_FILENO);
+
+ /* TODO: Support redirection of both stdout and stderr to the same
+ file using pipe(2) */
+
+ /* Execute the command */
+ execl("%%JAVA_HOME%%/%%JAVA_CMD%%", "%%JAVA_HOME%%/%%JAVA_CMD%%", "-jar", "%%JAR_FILE%%", NULL);
+
+ /* XXX: Improve this error message */
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: Unable to start %%APP_TITLE%% as '%%JAVA_HOME%%/%%JAVA_CMD%% -jar %%JAR_FILE%%' in %%APP_HOME%%: ");
+ perror(NULL);
+ } else {
+ printf(" [ DONE ]\n");
+ writePID(file, pid);
+ }
+}
+
+/**
+ * Stops the daemon.
+ */
+void stop(void) {
+
+ int file;
+ int pid;
+
+ /* Open and read the PID file */
+ file = openPIDFile();
+ pid = readPID(file);
+
+ printf(">> Checking that %%APP_TITLE%% is running...");
+
+ /* If there is a PID, see if the process still exists */
+ if (pid != -1) {
+ int result = kill(pid, 0);
+ if (result != 0 && errno == ESRCH) {
+ ftruncate(file, 0);
+ pid = -1;
+ }
+ }
+
+ /* If there is no running process, produce an error */
+ if (pid == -1) {
+ printf(" [ FAILED ]\n");
+ fprintf(stderr, "%%CONTROL_SCRIPT_NAME%%: %%APP_TITLE%% is currently not running.\n");
+ exit(ERR_NOT_RUNNING);
+ }
+
+ printf(" [ DONE ]\n");
+
+ killProcess(pid);
+
+ printf(">> Clearing PID file...");
+ ftruncate(file, 0);
+ printf(" [ DONE ]\n");
+}
+
+
+void restart(void) {
+ stop();
+ start();
+}
diff --git a/www/orion/files/orion.sh b/www/orion/files/orion.sh
index f76448b..2bff636 100644
--- a/www/orion/files/orion.sh
+++ b/www/orion/files/orion.sh
@@ -5,10 +5,10 @@ MYSELF=`basename $0`
case "$1" in
start)
- su -f -m %%USER%% -c "exec %%CONTROL_SCRIPT%% start" && echo -n ' %%APP_SHORTNAME%%'
+ su -f -m %%USER%% -c "exec %%CONTROL_SCRIPT%% start > /dev/null" && echo -n ' %%APP_SHORTNAME%%'
;;
stop)
- su -f -m %%USER%% -c "exec %%CONTROL_SCRIPT%% stop" && echo -n ' %%APP_SHORTNAME%%'
+ su -f -m %%USER%% -c "exec %%CONTROL_SCRIPT%% stop > /dev/null" && echo -n ' %%APP_SHORTNAME%%'
;;
*)
echo ""
diff --git a/www/orion/files/orionctl b/www/orion/files/orionctl
deleted file mode 100644
index d632538..0000000
--- a/www/orion/files/orionctl
+++ /dev/null
@@ -1,180 +0,0 @@
-#!/bin/sh
-
-# Set some variables
-APP_HOME=%%APP_HOME%%
-STDOUT_LOG=%%STDOUT_LOG%%
-STDERR_LOG=%%STDERR_LOG%%
-JAR_FILE=${APP_HOME}/orion.jar
-MYSELF=`basename $0`
-
-# Set the CLASSPATH
-unset CLASSPATH
-for i in ${APP_HOME}/lib/* ; do
- if [ "$CLASSPATH" != "" ]; then
- CLASSPATH=${CLASSPATH}:$i
- else
- CLASSPATH=$i
- fi
-done
-
-# Check if the JAVA_HOME directory is defined, otherwise set it to the
-# fallback default
-if [ "${JAVA_HOME}a" = "a" ]; then
- JAVA_HOME=%%JAVA_HOME%%
-fi
-if [ -f ${JAVA_HOME}/lib/tools.jar ] ; then
- CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar
-fi
-JAVA_CMD=${JAVA_HOME}/bin/java
-
-
-##############################################################################
-# Function that shows an error message
-#
-# This function is called by the 'checks' function
-#
-# Parameters:
-# 1: The message to be displayed.
-
-error() {
- echo -n "%%APP_SHORTNAME%%: ERROR: "
- echo $1
-}
-
-
-##############################################################################
-# Function that performs all checks necessary for starting or stopping the
-# application.
-#
-# This function is called by the 'start' and 'stop' functions
-#
-# This function expects no parameters
-
-checks() {
- # Make sure the application directory does exist
- if [ ! -d ${APP_HOME} ]; then
- error "Unable to find %%APP_TITLE%% home directory at ${APP_HOME}."
- exit 2
- fi
-
- # Make sure the application JAR file exists
- if [ ! -r ${JAR_FILE} ]; then
- error "Unable to find %%APP_TITLE%% JAR file at ${JAR_FILE}."
- exit 3
- fi
-
- # Make sure the Java VM can be found
- if [ ! -x ${JAVA_CMD} ]; then
- error "Unable to find Java VM at ${JAVA_HOME}."
- exit 4
- fi
-}
-
-
-##############################################################################
-# Functions that calls the application with the specified parameter
-#
-# Parameters:
-# 1: The argument to pass to the application (optional)
-
-app() {
- (cd ${APP_HOME} && ${JAVA_CMD} -cp ${CLASSPATH} -jar ${JAR_FILE} $1 &) >> ${STDOUT_LOG} 2>> ${STDERR_LOG}
-}
-
-
-##############################################################################
-# Function that starts the application
-#
-# This function is called from the main function
-#
-# This function expects no parameters
-
-start() {
- # Make sure the application is not started previously
- if [ -s %%PID_FILE%% ]; then
- error "%%APP_TITLE%% is probably already running. The PID file at %%PID_FILE%% is not empty."
- exit 1
- fi
-
- # Perform the checks that apply to stopping as well
- checks
-
- # Fix the permissions for the PID file, just in case
- chown %%USER%%:%%GROUP%% %%PID_FILE%%
- chmod 600 %%PID_FILE%%
-
- # Start the application
- echo -n ">> Starting %%APP_TITLE%%..."
- (cd ${APP_HOME} && ${JAVA_CMD} -jar ${JAR_FILE} & echo $! > %%PID_FILE%%) >> ${STDOUT_LOG} 2>> ${STDERR_LOG}
- if [ $? -eq 0 ]; then
- echo " [ DONE ]"
- else
- echo " [ FAILED ]"
- exit 13
- fi
-}
-
-
-##############################################################################
-# Function that stops the application
-#
-# This function is called from the main function
-#
-# This function expects no parameters
-
-stop() {
- # Perform the checks
- checks
-
- # Kill the running program
- if [ ! -s %%PID_FILE%% ]; then
- error "%%APP_TITLE%% is probably not running. The PID file at %%PID_FILE%% is empty."
- exit 16
- fi
- PID=`cat %%PID_FILE%%`
- echo -n ">> Killing %%APP_TITLE%% process (${PID})..."
- /bin/kill ${PID} > /dev/null 2> /dev/null
- if [ $? -eq 0 ]; then
- echo " [ DONE ]"
- else
- echo " [ FAILED ]"
- fi
- echo -n ">> Emptying PID file (%%PID_FILE%%)..."
- > %%PID_FILE%% 2> /dev/null
- if [ $? -eq 0 ]; then
- echo " [ DONE ]"
- else
- echo " [ FAILED ]"
- fi
-}
-
-
-##############################################################################
-# Main function. This function calls the 'start' and 'stop' functions.
-#
-# Parameters:
-# 1: The argument to this shell script
-
-main() {
- case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- stop
- start
- ;;
- *)
- echo "Usage: ${MYSELF} { start | stop | restart }"
- exit 64
- ;;
- esac
-}
-
-
-# Call the main function and exit
-main $1
-exit 0
OpenPOWER on IntegriCloud