Blame SOURCES/scl-utils-20130529-shebang.patch

d0d21f
d0d21f
https://bugzilla.redhat.com/show_bug.cgi?id=1372700
d0d21f
d0d21f
Backported from scl-utils-2.0.
d0d21f
d0d21f
--- scl-utils-20130529/scl.c.shebang
d0d21f
+++ scl-utils-20130529/scl.c
d0d21f
@@ -35,6 +35,74 @@
d0d21f
 #define SCL_CONF_DIR "/etc/scl/conf/"
d0d21f
 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
d0d21f
 
d0d21f
+static int count_words(const char *str, char ch)
d0d21f
+{
d0d21f
+    int count = 0;
d0d21f
+    bool inside_word = false;
d0d21f
+
d0d21f
+    while (*str != '\0') {
d0d21f
+        if (*str != ch) {
d0d21f
+            if (!inside_word) {
d0d21f
+                count++;
d0d21f
+            }
d0d21f
+            inside_word = true;
d0d21f
+        } else {
d0d21f
+            inside_word = false;
d0d21f
+        }
d0d21f
+        str++;
d0d21f
+    }
d0d21f
+
d0d21f
+    return count;
d0d21f
+}
d0d21f
+
d0d21f
+/**
d0d21f
+ * Procedure to parse shebang line and transform it to standard command
d0d21f
+ *
d0d21f
+ * In general, the shebang line has n parts at the beginnning:
d0d21f
+ * argv[0] => the name of the utility stated in shebang
d0d21f
+ * argv[1] => all the arguments as one string
d0d21f
+ * argv[2] => the script which was executed
d0d21f
+ * argv[n] => argument for executed script
d0d21f
+ *
d0d21f
+ * Considering the following shebang line in script ./test.py:
d0d21f
+ * #!/usr/bin/scl enable collectionX
d0d21f
+ * argv[0] = "/usr/bin/scl"
d0d21f
+ * argv[1] = "enable collectionX"
d0d21f
+ * argv[2] = "./test.py"
d0d21f
+ * argv[n] = "argn"
d0d21f
+ */
d0d21f
+static void parse_shebang(int argc, char *argv[],
d0d21f
+			  int *_shebang_argc, char ***_shebang_argv) {
d0d21f
+    int i = 0;
d0d21f
+    char *p;
d0d21f
+    int shebang_argc;
d0d21f
+    char **shebang_argv;
d0d21f
+
d0d21f
+    shebang_argc = count_words(argv[1], ' ') + argc - 1;
d0d21f
+    shebang_argv = (char **)malloc(sizeof(char *) * shebang_argc);
d0d21f
+    if (shebang_argv == NULL) {
d0d21f
+        fprintf(stderr, "Can't allocate memory.\n");
d0d21f
+        exit(EXIT_FAILURE);
d0d21f
+    }
d0d21f
+
d0d21f
+    shebang_argv[i++] = argv[0];
d0d21f
+
d0d21f
+    p = strtok(argv[1], " ");
d0d21f
+    while (p != NULL) {
d0d21f
+        shebang_argv[i++] = p;
d0d21f
+        p = strtok(NULL, " ");
d0d21f
+    }
d0d21f
+
d0d21f
+    while (i < shebang_argc) {
d0d21f
+        shebang_argv[i] = argv[i - (shebang_argc - argc)];
d0d21f
+        i++;
d0d21f
+    }
d0d21f
+
d0d21f
+    *_shebang_argc = shebang_argc;
d0d21f
+    *_shebang_argv = shebang_argv;
d0d21f
+}
d0d21f
+
d0d21f
+
d0d21f
 static void check_asprintf( char **strp, const char *fmt, ... ) {
d0d21f
 	va_list args;
d0d21f
 
d0d21f
@@ -648,6 +716,17 @@
d0d21f
 		}
d0d21f
 	}
d0d21f
 
d0d21f
+	if (argc >= 3 && strchr(argv[1], ' ') != NULL) {
d0d21f
+		/* Apparently a shebang line */
d0d21f
+		char **fake_argv = argv;
d0d21f
+		int fake_argc = argc;
d0d21f
+		
d0d21f
+		parse_shebang(argc, argv, &fake_argc, &fake_argv);
d0d21f
+		
d0d21f
+		argc = fake_argc;
d0d21f
+		argv = fake_argv;
d0d21f
+	}
d0d21f
+
d0d21f
 	for (i = 0; i < argc; i++) {
d0d21f
 		if (strcmp(argv[i], "--") == 0) {
d0d21f
 			break;