|
|
28453c |
From f5bf4407d7801d5add15b786a7425b6135dfb7e2 Mon Sep 17 00:00:00 2001
|
|
|
28453c |
From: Jan Zeleny <jzeleny@redhat.com>
|
|
|
28453c |
Date: Thu, 21 Nov 2013 12:18:46 +0100
|
|
|
28453c |
Subject: [PATCH] Implement "--" as a command separator
|
|
|
28453c |
|
|
|
28453c |
Whatever comes after the first "--" will be considered a command. If there
|
|
|
28453c |
are multiple arguments after the first "--", they will all be concatenated by
|
|
|
28453c |
spaces and treated as a single command afterwards.
|
|
|
28453c |
---
|
|
|
28453c |
scl.1 | 9 ++++++-
|
|
|
28453c |
scl.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++----------------
|
|
|
28453c |
2 files changed, 76 insertions(+), 21 deletions(-)
|
|
|
28453c |
|
|
|
28453c |
diff --git a/scl.1 b/scl.1
|
|
|
28453c |
index aa797739b1faafe8760e9fc7c5ddaa6ef5da5f4f..f552653f82e97e6503e81f5f75d63b8ca0429bfa 100644
|
|
|
28453c |
--- a/scl.1
|
|
|
28453c |
+++ b/scl.1
|
|
|
28453c |
@@ -5,6 +5,8 @@ scl \- Setup and run software from Software Collection environment
|
|
|
28453c |
.PP
|
|
|
28453c |
\fBscl\fP \fI<action>\fR \fI<collection1>\fR [\fI<collection2> ...\fR] \fI<command>\fR
|
|
|
28453c |
.PP
|
|
|
28453c |
+\fBscl\fP \fI<action>\fR \fI<collection1>\fR [\fI<collection2> ...\fR] -- \fI<command>\fR
|
|
|
28453c |
+.PP
|
|
|
28453c |
\fBscl\fP {\fB-l|--list\fP} [\fI<collection1> <collection2> ...\fR]
|
|
|
28453c |
.SH "DESCRIPTION"
|
|
|
28453c |
.PP
|
|
|
28453c |
@@ -27,6 +29,10 @@ collections which are enabled by the left-right order as present on \fBscl\fP co
|
|
|
28453c |
Collection environment enabled. Control is returned back to the caller with the original
|
|
|
28453c |
environment as soon as the command finishes. It \fI<command>\fR is '-' (dash) then it is
|
|
|
28453c |
read from the standard input.
|
|
|
28453c |
+.PP
|
|
|
28453c |
+Note that if you use \fI<command>\fR consisting of multiple arguments, you either need to
|
|
|
28453c |
+use quotes or the \fB--\fP command separator. Everything that follows the
|
|
|
28453c |
+separator will be considered a command or its argument.
|
|
|
28453c |
.SH "OPTIONS"
|
|
|
28453c |
.PP
|
|
|
28453c |
.IP "\fB-l, --list\fP"
|
|
|
28453c |
@@ -52,4 +58,5 @@ scl -l example
|
|
|
28453c |
list all packages within example collection
|
|
|
28453c |
.SH "AUTHOR"
|
|
|
28453c |
.PP
|
|
|
28453c |
-\fBscl\fP was written by Jindrich Novy <jnovy@redhat.com>.
|
|
|
28453c |
+\fBscl\fP was written by Jindrich Novy <jnovy@redhat.com> and Jan Zeleny
|
|
|
28453c |
+<jzeleny@redhat.com>
|
|
|
28453c |
diff --git a/scl.c b/scl.c
|
|
|
28453c |
index 81fdf5d94a9e011d697cd422cd581d21364d7eca..cf3ff5bfa7fce0b95705b0aa09946524d06801c5 100644
|
|
|
28453c |
--- a/scl.c
|
|
|
28453c |
+++ b/scl.c
|
|
|
28453c |
@@ -31,6 +31,7 @@
|
|
|
28453c |
#include <fcntl.h>
|
|
|
28453c |
|
|
|
28453c |
#define SCL_CONF_DIR "/etc/scl/conf/"
|
|
|
28453c |
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
|
|
|
28453c |
|
|
|
28453c |
static void check_asprintf( char **strp, const char *fmt, ... ) {
|
|
|
28453c |
va_list args;
|
|
|
28453c |
@@ -245,8 +246,10 @@ int main(int argc, char **argv) {
|
|
|
28453c |
struct stat st;
|
|
|
28453c |
char *path, *enablepath;
|
|
|
28453c |
char tmp[] = "/var/tmp/sclXXXXXX";
|
|
|
28453c |
- char *cmd = NULL, *bash_cmd, *echo, *enabled;
|
|
|
28453c |
- int i, tfd, ffd, stdin_read = 0;
|
|
|
28453c |
+ char *bash_cmd, *echo, *enabled;
|
|
|
28453c |
+ int i, tfd, ffd;
|
|
|
28453c |
+ int separator_pos = 0;
|
|
|
28453c |
+ char *command = NULL;
|
|
|
28453c |
|
|
|
28453c |
if (argc == 2 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h"))) {
|
|
|
28453c |
print_usage(argv[0]);
|
|
|
28453c |
@@ -263,25 +266,58 @@ int main(int argc, char **argv) {
|
|
|
28453c |
exit(EXIT_SUCCESS);
|
|
|
28453c |
}
|
|
|
28453c |
|
|
|
28453c |
- if (!strcmp(argv[argc-1], "-")) { /* reading command from stdin */
|
|
|
28453c |
- size_t r;
|
|
|
28453c |
+ for (i = 0; i < argc; i++) {
|
|
|
28453c |
+ if (strcmp(argv[i], "--") == 0) {
|
|
|
28453c |
+ break;
|
|
|
28453c |
+ }
|
|
|
28453c |
+ }
|
|
|
28453c |
+ separator_pos = i;
|
|
|
28453c |
|
|
|
28453c |
+ if (separator_pos == argc) {
|
|
|
28453c |
+ /* Separator not found */
|
|
|
28453c |
if (argc < 4) {
|
|
|
28453c |
- fprintf(stderr, "Need at least 3 arguments.\nRun %s without arguments to get help.\n", argv[0]);
|
|
|
28453c |
+ fprintf(stderr, "Need at least 3 arguments.\nRun %s --help to get help.\n", argv[0]);
|
|
|
28453c |
exit(EXIT_FAILURE);
|
|
|
28453c |
}
|
|
|
28453c |
|
|
|
28453c |
- cmd = malloc(BUFSIZ);
|
|
|
28453c |
+ command = strdup(argv[argc-1]);
|
|
|
28453c |
+ if (command == NULL) {
|
|
|
28453c |
+ fprintf(stderr, "Can't duplicate string.\n");
|
|
|
28453c |
+ }
|
|
|
28453c |
+ } else if (separator_pos == argc-1) {
|
|
|
28453c |
+ command = "-";
|
|
|
28453c |
+ } else if (separator_pos <= 2) {
|
|
|
28453c |
+ fprintf(stderr, "Need at least 2 arguments before command is specified.\nRun %s --help to get help.\n", argv[0]);
|
|
|
28453c |
+ exit(EXIT_FAILURE);
|
|
|
28453c |
+ } else {
|
|
|
28453c |
+ command = NULL;
|
|
|
28453c |
+ }
|
|
|
28453c |
|
|
|
28453c |
- if (!cmd) {
|
|
|
28453c |
+ if ((command == NULL && !strcmp(argv[separator_pos+1], "-")) ||
|
|
|
28453c |
+ (command != NULL && !strcmp(command, "-"))) { /* reading command from stdin */
|
|
|
28453c |
+ size_t r;
|
|
|
28453c |
+
|
|
|
28453c |
+
|
|
|
28453c |
+ command = malloc(BUFSIZ+1);
|
|
|
28453c |
+ if (!command) {
|
|
|
28453c |
fprintf(stderr, "Can't allocate memory.\n");
|
|
|
28453c |
exit(EXIT_FAILURE);
|
|
|
28453c |
}
|
|
|
28453c |
|
|
|
28453c |
- for (r=0; (r += fread(cmd+r, 1, BUFSIZ, stdin));) {
|
|
|
28453c |
- if (feof(stdin)) break;
|
|
|
28453c |
- cmd = realloc(cmd, r+BUFSIZ);
|
|
|
28453c |
- if (!cmd) {
|
|
|
28453c |
+ for (r=0; (r += fread(command+r, 1, BUFSIZ, stdin));) {
|
|
|
28453c |
+ if (feof(stdin)) {
|
|
|
28453c |
+ if (r % BUFSIZ == 0) {
|
|
|
28453c |
+ command = realloc(command, r+1);
|
|
|
28453c |
+ if (!command) {
|
|
|
28453c |
+ fprintf(stderr, "Can't reallocate memory.\n");
|
|
|
28453c |
+ exit(EXIT_FAILURE);
|
|
|
28453c |
+ }
|
|
|
28453c |
+ }
|
|
|
28453c |
+ command[r] = '\0';
|
|
|
28453c |
+ break;
|
|
|
28453c |
+ }
|
|
|
28453c |
+ command = realloc(command, r+BUFSIZ+1);
|
|
|
28453c |
+ if (!command) {
|
|
|
28453c |
fprintf(stderr, "Can't reallocate memory.\n");
|
|
|
28453c |
exit(EXIT_FAILURE);
|
|
|
28453c |
}
|
|
|
28453c |
@@ -290,15 +326,27 @@ int main(int argc, char **argv) {
|
|
|
28453c |
fprintf(stderr, "Error reading command from stdin.\n");
|
|
|
28453c |
exit(EXIT_FAILURE);
|
|
|
28453c |
}
|
|
|
28453c |
- stdin_read = 1;
|
|
|
28453c |
- }
|
|
|
28453c |
+ } else if (command == NULL) {
|
|
|
28453c |
+ int len = 0;
|
|
|
28453c |
+ for (i = separator_pos+1; i < argc; i++) {
|
|
|
28453c |
+ len += strlen(argv[i])+3; /* +1 for additional space, +2 for additional quotes */
|
|
|
28453c |
+ }
|
|
|
28453c |
|
|
|
28453c |
- if (!stdin_read) {
|
|
|
28453c |
- if (argc < 4) {
|
|
|
28453c |
- print_usage(argv[0]);
|
|
|
28453c |
+ command = malloc((len+1)*sizeof(char));
|
|
|
28453c |
+ if (command == NULL) {
|
|
|
28453c |
+ fprintf(stderr, "Can't allocate memory.\n");
|
|
|
28453c |
exit(EXIT_FAILURE);
|
|
|
28453c |
}
|
|
|
28453c |
- cmd = strdup(argv[argc-1]);
|
|
|
28453c |
+
|
|
|
28453c |
+ len = 0;
|
|
|
28453c |
+ for (i = separator_pos+1; i < argc; i++) {
|
|
|
28453c |
+ command[len++] = '"';
|
|
|
28453c |
+ strcpy(command+len, argv[i]);
|
|
|
28453c |
+ len += strlen(argv[i]);
|
|
|
28453c |
+ command[len++] = '"';
|
|
|
28453c |
+ command[len++] = ' ';
|
|
|
28453c |
+ }
|
|
|
28453c |
+ command[len] = '\0';
|
|
|
28453c |
}
|
|
|
28453c |
|
|
|
28453c |
tfd = mkstemp(tmp);
|
|
|
28453c |
@@ -307,7 +355,7 @@ int main(int argc, char **argv) {
|
|
|
28453c |
write_script(tfd, enabled);
|
|
|
28453c |
free(enabled);
|
|
|
28453c |
|
|
|
28453c |
- for (i=2; i
|
|
|
28453c |
+ for (i=2; i
|
|
|
28453c |
FILE *f;
|
|
|
28453c |
size_t r;
|
|
|
28453c |
char scl_dir[BUFSIZ];
|
|
|
28453c |
@@ -367,9 +415,9 @@ int main(int argc, char **argv) {
|
|
|
28453c |
free(path);
|
|
|
28453c |
}
|
|
|
28453c |
|
|
|
28453c |
- write_script(tfd, cmd);
|
|
|
28453c |
+ write_script(tfd, command);
|
|
|
28453c |
write_script(tfd, "\n");
|
|
|
28453c |
- free(cmd);
|
|
|
28453c |
+ free(command);
|
|
|
28453c |
close(tfd);
|
|
|
28453c |
|
|
|
28453c |
check_asprintf(&bash_cmd, "/bin/bash %s", tmp);
|
|
|
28453c |
--
|
|
|
28453c |
1.8.3.1
|
|
|
28453c |
|