1f6233d23SIngo Weinhold/*
2f6233d23SIngo Weinhold * Copyright 2005-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
3f6233d23SIngo Weinhold * Distributed under the terms of the MIT License.
4f6233d23SIngo Weinhold */
5f6233d23SIngo Weinhold
6f6233d23SIngo Weinhold#include "fs_shell_command.h"
7f6233d23SIngo Weinhold
8f6233d23SIngo Weinhold#include <stdio.h>
9f6233d23SIngo Weinhold#include <stdlib.h>
10f6233d23SIngo Weinhold#include <string.h>
11f6233d23SIngo Weinhold
12f6233d23SIngo Weinhold
13f6233d23SIngo Weinholdstatic void
14f6233d23SIngo Weinholdadd_char(char *&buffer, int &bufferSize, char c)
15f6233d23SIngo Weinhold{
16f6233d23SIngo Weinhold	if (bufferSize <= 0) {
17f6233d23SIngo Weinhold		fprintf(stderr, "Error: Command line too long\n");
18f6233d23SIngo Weinhold		exit(1);
19f6233d23SIngo Weinhold	}
20f6233d23SIngo Weinhold
21f6233d23SIngo Weinhold	*buffer = c;
22f6233d23SIngo Weinhold	buffer++;
23f6233d23SIngo Weinhold	bufferSize--;
24f6233d23SIngo Weinhold}
25f6233d23SIngo Weinhold
26f6233d23SIngo Weinhold
27f6233d23SIngo Weinholdstatic void
28f6233d23SIngo Weinholdprepare_command_string(const char *const *argv, int argc, char *buffer,
29f6233d23SIngo Weinhold		int bufferSize)
30f6233d23SIngo Weinhold{
31f6233d23SIngo Weinhold	for (int argi = 0; argi < argc; argi++) {
32f6233d23SIngo Weinhold		const char *arg = argv[argi];
33f6233d23SIngo Weinhold
34f6233d23SIngo Weinhold		if (argi > 0)
35f6233d23SIngo Weinhold			add_char(buffer, bufferSize, ' ');
36f6233d23SIngo Weinhold
37f6233d23SIngo Weinhold		while (*arg) {
38aeb21518SIngo Weinhold			if (strchr(" \"'\\", *arg))
39f6233d23SIngo Weinhold				add_char(buffer, bufferSize, '\\');
40f6233d23SIngo Weinhold			add_char(buffer, bufferSize, *arg);
41f6233d23SIngo Weinhold			arg++;
42f6233d23SIngo Weinhold		}
43f6233d23SIngo Weinhold	}
44f6233d23SIngo Weinhold
45f6233d23SIngo Weinhold	add_char(buffer, bufferSize, '\0');
46f6233d23SIngo Weinhold}
47f6233d23SIngo Weinhold
48f6233d23SIngo Weinhold
49f6233d23SIngo Weinholdint
50f6233d23SIngo Weinholdmain(int argc, const char *const *argv)
51f6233d23SIngo Weinhold{
52f6233d23SIngo Weinhold	if (argc < 2) {
53f6233d23SIngo Weinhold		fprintf(stderr, "Error: No command given.\n");
54f6233d23SIngo Weinhold		exit(1);
55f6233d23SIngo Weinhold	}
56f6233d23SIngo Weinhold
5717ebe2b0SIngo Weinhold	if (strcmp(argv[1], "--uses-fifos") == 0)
5817ebe2b0SIngo Weinhold		exit(gUsesFifos ? 0 : 1);
5917ebe2b0SIngo Weinhold
60f6233d23SIngo Weinhold	// prepare the command string
61f6233d23SIngo Weinhold	char command[102400];
62f6233d23SIngo Weinhold	prepare_command_string(argv + 1, argc - 1, command, sizeof(command));
63f6233d23SIngo Weinhold
64f6233d23SIngo Weinhold	// send the command
65f6233d23SIngo Weinhold	int result;
66f6233d23SIngo Weinhold	if (!send_external_command(command, &result))
67f6233d23SIngo Weinhold		exit(1);
68f6233d23SIngo Weinhold
69f6233d23SIngo Weinhold	// evaluate result
70f6233d23SIngo Weinhold	if (result != 0) {
71f6233d23SIngo Weinhold		fprintf(stderr, "Error: Command failed: %s\n", strerror(result));
72f6233d23SIngo Weinhold		fprintf(stderr, "Error: Command was:\n  %s\n", command);
73f6233d23SIngo Weinhold		exit(1);
74f6233d23SIngo Weinhold	}
75f6233d23SIngo Weinhold
76f6233d23SIngo Weinhold	return 0;
77f6233d23SIngo Weinhold}
78f6233d23SIngo Weinhold
79