From ae92cc208dc50de0e17f0505ff70f80bd2f14484 Mon Sep 17 00:00:00 2001 From: Philip Homburg Date: Thu, 11 May 2006 15:30:56 +0000 Subject: [PATCH] The new service command managed to escape. --- servers/rs/service.c | 121 ++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/servers/rs/service.c b/servers/rs/service.c index e7b3321e3..e4c929068 100644 --- a/servers/rs/service.c +++ b/servers/rs/service.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -39,11 +40,13 @@ extern int errno; * argument pairs like "-args arglist" follow. */ #define ARG_NAME 0 /* own application name */ -#define ARG_REQUEST 1 /* request to perform */ -#define ARG_PATH 2 /* rescue dir or system service */ -#define ARG_PID 2 /* pid of system service */ -#define MIN_ARG_COUNT 2 /* require an action */ +/* The following are relative to optind */ +#define ARG_REQUEST 0 /* request to perform */ +#define ARG_PATH 1 /* rescue dir or system service */ +#define ARG_PID 1 /* pid of system service */ + +#define MIN_ARG_COUNT 1 /* require an action */ #define ARG_ARGS "-args" /* list of arguments to be passed */ #define ARG_DEV "-dev" /* major device number for drivers */ @@ -71,7 +74,7 @@ PRIVATE void print_usage(char *app_name, char *problem) { printf("Warning, %s\n", problem); printf("Usage:\n"); - printf(" %s up [%s ] [%s ] [%s ]\n", + printf(" %s [-c] up [%s ] [%s ] [%s ]\n", app_name, ARG_ARGS, ARG_DEV, ARG_PERIOD); printf(" %s down \n", app_name); printf(" %s refresh \n", app_name); @@ -84,7 +87,7 @@ PRIVATE void print_usage(char *app_name, char *problem) */ PRIVATE void failure(int num) { - printf("Request to RS failed: %s (%d)\n", strerror(num), num); + printf("Request to RS failed: %s (error %d)\n", strerror(num), num); exit(num); } @@ -92,41 +95,63 @@ PRIVATE void failure(int num) /* Parse and verify correctness of arguments. Report problem and exit if an * error is found. Store needed parameters in global variables. */ -PRIVATE int parse_arguments(int argc, char **argv) +PRIVATE int parse_arguments(int argcX, char **argvX) { struct stat stat_buf; char *hz; int req_nr; - int i; + int c, i; + int c_flag; + + c_flag= 0; + while (c= getopt(argcX, argvX, "c?"), c != -1) + { + switch(c) + { + case '?': + print_usage(argvX[ARG_NAME], "wrong number of arguments"); + exit(EINVAL); + case 'c': + c_flag= 1; + break; + default: + fprintf(stderr, "%s: getopt failed: %c\n", + argvX[ARG_NAME], c); + exit(1); + } + } /* Verify argument count. */ - if (argc < MIN_ARG_COUNT) { - print_usage(argv[ARG_NAME], "wrong number of arguments"); + if (argcX < optind+MIN_ARG_COUNT) { + print_usage(argvX[ARG_NAME], "wrong number of arguments"); exit(EINVAL); } /* Verify request type. */ for (req_type=0; req_type< ILLEGAL_REQUEST; req_type++) { - if (strcmp(known_requests[req_type],argv[ARG_REQUEST])==0) break; + if (strcmp(known_requests[req_type],argvX[optind+ARG_REQUEST])==0) break; } if (req_type == ILLEGAL_REQUEST) { - print_usage(argv[ARG_NAME], "illegal request type"); + print_usage(argvX[ARG_NAME], "illegal request type"); exit(ENOSYS); } req_nr = RS_RQ_BASE + req_type; if (req_nr == RS_UP) { + if (c_flag) + req_nr= RS_UP_COPY; + /* Verify argument count. */ - if (argc - 1 < ARG_PATH) { - print_usage(argv[ARG_NAME], "action requires a binary to start"); + if (argcX - 1 < optind+ARG_PATH) { + print_usage(argvX[ARG_NAME], "action requires a binary to start"); exit(EINVAL); } /* Verify the name of the binary of the system service. */ - req_path = argv[ARG_PATH]; + req_path = argvX[optind+ARG_PATH]; if (req_path[0] != '/') { - print_usage(argv[ARG_NAME], "binary should be absolute path"); + print_usage(argvX[ARG_NAME], "binary should be absolute path"); exit(EINVAL); } if (stat(req_path, &stat_buf) == -1) { @@ -135,43 +160,44 @@ PRIVATE int parse_arguments(int argc, char **argv) exit(errno); } if (! (stat_buf.st_mode & S_IFREG)) { - print_usage(argv[ARG_NAME], "binary is not a regular file"); + print_usage(argvX[ARG_NAME], "binary is not a regular file"); exit(EINVAL); } /* Check optional arguments that come in pairs like "-args arglist". */ - for (i=MIN_ARG_COUNT+1; i> MAJOR) & BYTE; } - else if (strcmp(argv[i], ARG_ARGS)==0) { - req_priv = argv[i+1]; + else if (strcmp(argvX[i], ARG_ARGS)==0) { + req_priv = argvX[i+1]; } else { - print_usage(argv[ARG_NAME], "unknown optional argument given"); + print_usage(argvX[ARG_NAME], "unknown optional argument given"); exit(EINVAL); } } @@ -179,33 +205,33 @@ PRIVATE int parse_arguments(int argc, char **argv) else if (req_nr == RS_DOWN || req_nr == RS_REFRESH) { /* Verify argument count. */ - if (argc - 1 < ARG_PID) { - print_usage(argv[ARG_NAME], "action requires a pid to stop"); + if (argcX - 1 < optind+ARG_PID) { + print_usage(argvX[ARG_NAME], "action requires a pid to stop"); exit(EINVAL); } - if (! (req_pid = atoi(argv[ARG_PID])) > 0) { - print_usage(argv[ARG_NAME], "pid must be greater than zero"); + if (! (req_pid = atoi(argvX[optind+ARG_PID])) > 0) { + print_usage(argvX[ARG_NAME], "pid must be greater than zero"); exit(EINVAL); } } else if (req_nr == RS_RESCUE) { /* Verify argument count. */ - if (argc - 1 < ARG_PATH) { - print_usage(argv[ARG_NAME], "action requires rescue directory"); + if (argcX - 1 < optind+ARG_PATH) { + print_usage(argvX[ARG_NAME], "action requires rescue directory"); exit(EINVAL); } - req_path = argv[ARG_PATH]; + req_path = argvX[optind+ARG_PATH]; if (req_path[0] != '/') { - print_usage(argv[ARG_NAME], "rescue dir should be absolute path"); + print_usage(argvX[ARG_NAME], "rescue dir should be absolute path"); exit(EINVAL); } - if (stat(argv[ARG_PATH], &stat_buf) == -1) { - print_usage(argv[ARG_NAME], "couldn't get status of directory"); + if (stat(argvX[optind+ARG_PATH], &stat_buf) == -1) { + print_usage(argvX[ARG_NAME], "couldn't get status of directory"); exit(errno); } if ( ! (stat_buf.st_mode & S_IFDIR)) { - print_usage(argv[ARG_NAME], "file is not a directory"); + print_usage(argvX[ARG_NAME], "file is not a directory"); exit(EINVAL); } } @@ -239,6 +265,7 @@ PUBLIC int main(int argc, char **argv) */ switch(request) { case RS_UP: + case RS_UP_COPY: /* Build space-separated command string to be passed to RS server. */ strcpy(command, req_path); command[strlen(req_path)] = ' '; @@ -250,24 +277,24 @@ PUBLIC int main(int argc, char **argv) m.RS_DEV_MAJOR = req_major; m.RS_PERIOD = req_period; if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) - failure(s); + failure(-s); result = m.m_type; break; case RS_DOWN: case RS_REFRESH: m.RS_PID = req_pid; if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) - failure(s); + failure(-s); break; case RS_RESCUE: m.RS_CMD_ADDR = req_path; m.RS_CMD_LEN = strlen(req_path); if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) - failure(s); + failure(-s); break; case RS_SHUTDOWN: if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) - failure(s); + failure(-s); break; default: print_usage(argv[ARG_NAME], "request is not yet supported");