Blame SOURCES/0002-Implement-as-a-command-separator.patch

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