|
Packit Service |
ada5e0 |
/* Minimal /bin/sh for in-container use.
|
|
Packit Service |
ada5e0 |
Copyright (C) 2018 Free Software Foundation, Inc.
|
|
Packit Service |
ada5e0 |
This file is part of the GNU C Library.
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
The GNU C Library is free software; you can redistribute it and/or
|
|
Packit Service |
ada5e0 |
modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
ada5e0 |
License as published by the Free Software Foundation; either
|
|
Packit Service |
ada5e0 |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
The GNU C Library is distributed in the hope that it will be useful,
|
|
Packit Service |
ada5e0 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
ada5e0 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
ada5e0 |
Lesser General Public License for more details.
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
ada5e0 |
License along with the GNU C Library; if not, see
|
|
Packit Service |
ada5e0 |
<http://www.gnu.org/licenses/>. */
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
#define _FILE_OFFSET_BITS 64
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
#include <stdio.h>
|
|
Packit Service |
ada5e0 |
#include <stdlib.h>
|
|
Packit Service |
ada5e0 |
#include <string.h>
|
|
Packit Service |
ada5e0 |
#include <sched.h>
|
|
Packit Service |
ada5e0 |
#include <sys/syscall.h>
|
|
Packit Service |
ada5e0 |
#include <unistd.h>
|
|
Packit Service |
ada5e0 |
#include <sys/types.h>
|
|
Packit Service |
ada5e0 |
#include <dirent.h>
|
|
Packit Service |
ada5e0 |
#include <string.h>
|
|
Packit Service |
ada5e0 |
#include <sys/stat.h>
|
|
Packit Service |
ada5e0 |
#include <sys/fcntl.h>
|
|
Packit Service |
ada5e0 |
#include <sys/file.h>
|
|
Packit Service |
ada5e0 |
#include <sys/wait.h>
|
|
Packit Service |
ada5e0 |
#include <stdarg.h>
|
|
Packit Service |
ada5e0 |
#include <sys/sysmacros.h>
|
|
Packit Service |
ada5e0 |
#include <ctype.h>
|
|
Packit Service |
ada5e0 |
#include <utime.h>
|
|
Packit Service |
ada5e0 |
#include <errno.h>
|
|
Packit Service |
ada5e0 |
#include <error.h>
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
#include <support/support.h>
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Design considerations
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
General rule: optimize for developer time, not run time.
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
Specifically:
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
* Don't worry about slow algorithms
|
|
Packit Service |
ada5e0 |
* Don't worry about free'ing memory
|
|
Packit Service |
ada5e0 |
* Don't implement anything the testsuite doesn't need.
|
|
Packit Service |
ada5e0 |
* Line and argument counts are limited, see below.
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
*/
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
#define MAX_ARG_COUNT 100
|
|
Packit Service |
ada5e0 |
#define MAX_LINE_LENGTH 1000
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Debugging is enabled via --debug, which must be the first argument. */
|
|
Packit Service |
ada5e0 |
static int debug_mode = 0;
|
|
Packit Service |
ada5e0 |
#define dprintf if (debug_mode) fprintf
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Emulate the "/bin/true" command. Arguments are ignored. */
|
|
Packit Service |
ada5e0 |
static int
|
|
Packit Service |
ada5e0 |
true_func (char **argv)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
return 0;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Emulate the "/bin/echo" command. Options are ignored, arguments
|
|
Packit Service |
ada5e0 |
are printed to stdout. */
|
|
Packit Service |
ada5e0 |
static int
|
|
Packit Service |
ada5e0 |
echo_func (char **argv)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
int i;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
for (i = 0; argv[i]; i++)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
if (i > 0)
|
|
Packit Service |
ada5e0 |
putchar (' ');
|
|
Packit Service |
ada5e0 |
fputs (argv[i], stdout);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
putchar ('\n');
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
return 0;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Emulate the "/bin/cp" command. Options are ignored. Only copies
|
|
Packit Service |
ada5e0 |
one source file to one destination file. Directory destinations
|
|
Packit Service |
ada5e0 |
are not supported. */
|
|
Packit Service |
ada5e0 |
static int
|
|
Packit Service |
ada5e0 |
copy_func (char **argv)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
char *sname = argv[0];
|
|
Packit Service |
ada5e0 |
char *dname = argv[1];
|
|
Packit Service |
ada5e0 |
int sfd, dfd;
|
|
Packit Service |
ada5e0 |
struct stat st;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
sfd = open (sname, O_RDONLY);
|
|
Packit Service |
ada5e0 |
if (sfd < 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "cp: unable to open %s for reading: %s\n",
|
|
Packit Service |
ada5e0 |
sname, strerror (errno));
|
|
Packit Service |
ada5e0 |
return 1;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (fstat (sfd, &st) < 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "cp: unable to fstat %s: %s\n",
|
|
Packit Service |
ada5e0 |
sname, strerror (errno));
|
|
Packit Service |
ada5e0 |
return 1;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
|
|
Packit Service |
ada5e0 |
if (dfd < 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "cp: unable to open %s for writing: %s\n",
|
|
Packit Service |
ada5e0 |
dname, strerror (errno));
|
|
Packit Service |
ada5e0 |
return 1;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (support_copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "cp: cannot copy file %s to %s: %s\n",
|
|
Packit Service |
ada5e0 |
sname, dname, strerror (errno));
|
|
Packit Service |
ada5e0 |
return 1;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
close (sfd);
|
|
Packit Service |
ada5e0 |
close (dfd);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
chmod (dname, st.st_mode & 0777);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
return 0;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* This is a list of all the built-in commands we understand. */
|
|
Packit Service |
ada5e0 |
static struct {
|
|
Packit Service |
ada5e0 |
const char *name;
|
|
Packit Service |
ada5e0 |
int (*func) (char **argv);
|
|
Packit Service |
ada5e0 |
} builtin_funcs[] = {
|
|
Packit Service |
ada5e0 |
{ "true", true_func },
|
|
Packit Service |
ada5e0 |
{ "echo", echo_func },
|
|
Packit Service |
ada5e0 |
{ "cp", copy_func },
|
|
Packit Service |
ada5e0 |
{ NULL, NULL }
|
|
Packit Service |
ada5e0 |
};
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Run one tokenized command. argv[0] is the command. argv is
|
|
Packit Service |
ada5e0 |
NULL-terminated. */
|
|
Packit Service |
ada5e0 |
static void
|
|
Packit Service |
ada5e0 |
run_command_array (char **argv)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
int i, j;
|
|
Packit Service |
ada5e0 |
pid_t pid;
|
|
Packit Service |
ada5e0 |
int status;
|
|
Packit Service |
ada5e0 |
int (*builtin_func) (char **args);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (argv[0] == NULL)
|
|
Packit Service |
ada5e0 |
return;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
builtin_func = NULL;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
int new_stdin = 0;
|
|
Packit Service |
ada5e0 |
int new_stdout = 1;
|
|
Packit Service |
ada5e0 |
int new_stderr = 2;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "run_command_array starting\n");
|
|
Packit Service |
ada5e0 |
for (i = 0; argv[i]; i++)
|
|
Packit Service |
ada5e0 |
dprintf (stderr, " argv [%d] `%s'\n", i, argv[i]);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
for (j = i = 0; argv[i]; i++)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[i], "<") == 0 && argv[i + 1])
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
new_stdin = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777);
|
|
Packit Service |
ada5e0 |
++i;
|
|
Packit Service |
ada5e0 |
continue;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[i], ">") == 0 && argv[i + 1])
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777);
|
|
Packit Service |
ada5e0 |
++i;
|
|
Packit Service |
ada5e0 |
continue;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[i], ">>") == 0 && argv[i + 1])
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
new_stdout = open (argv[i + 1], O_WRONLY|O_CREAT|O_APPEND, 0777);
|
|
Packit Service |
ada5e0 |
++i;
|
|
Packit Service |
ada5e0 |
continue;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[i], "2>") == 0 && argv[i + 1])
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
new_stderr = open (argv[i + 1], O_WRONLY|O_CREAT|O_TRUNC, 0777);
|
|
Packit Service |
ada5e0 |
++i;
|
|
Packit Service |
ada5e0 |
continue;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
argv[j++] = argv[i];
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
argv[j] = NULL;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
for (i = 0; builtin_funcs[i].name != NULL; i++)
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[0], builtin_funcs[i].name) == 0)
|
|
Packit Service |
ada5e0 |
builtin_func = builtin_funcs[i].func;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "builtin %p argv0 `%s'\n", builtin_func, argv[0]);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
pid = fork ();
|
|
Packit Service |
ada5e0 |
if (pid < 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "sh: fork failed\n");
|
|
Packit Service |
ada5e0 |
exit (1);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (pid == 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
if (new_stdin != 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
dup2 (new_stdin, 0);
|
|
Packit Service |
ada5e0 |
close (new_stdin);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
if (new_stdout != 1)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
dup2 (new_stdout, 1);
|
|
Packit Service |
ada5e0 |
close (new_stdout);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
if (new_stderr != 2)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
dup2 (new_stderr, 2);
|
|
Packit Service |
ada5e0 |
close (new_stdout);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (builtin_func != NULL)
|
|
Packit Service |
ada5e0 |
exit (builtin_func (argv + 1));
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
execvp (argv[0], argv);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "sh: execing %s failed: %s",
|
|
Packit Service |
ada5e0 |
argv[0], strerror (errno));
|
|
Packit Service |
ada5e0 |
exit (1);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
waitpid (pid, &status, 0);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "exiting run_command_array\n");
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (WIFEXITED (status))
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
int rv = WEXITSTATUS (status);
|
|
Packit Service |
ada5e0 |
if (rv)
|
|
Packit Service |
ada5e0 |
exit (rv);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
else
|
|
Packit Service |
ada5e0 |
exit (1);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Run one command-as-a-string, by tokenizing it. Limited to
|
|
Packit Service |
ada5e0 |
MAX_ARG_COUNT arguments. Simple substitution is done of $1 to $9
|
|
Packit Service |
ada5e0 |
(as whole separate tokens) from iargs[]. Quoted strings work if
|
|
Packit Service |
ada5e0 |
the quotes wrap whole tokens; i.e. "foo bar" but not foo" bar". */
|
|
Packit Service |
ada5e0 |
static void
|
|
Packit Service |
ada5e0 |
run_command_string (const char *cmdline, const char **iargs)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
char *args[MAX_ARG_COUNT+1];
|
|
Packit Service |
ada5e0 |
int ap = 0;
|
|
Packit Service |
ada5e0 |
const char *start, *end;
|
|
Packit Service |
ada5e0 |
int nargs;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
for (nargs = 0; iargs[nargs] != NULL; ++nargs)
|
|
Packit Service |
ada5e0 |
;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "run_command_string starting: '%s'\n", cmdline);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
while (ap < MAX_ARG_COUNT)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
/* If the argument is quoted, this is the quote character, else NUL. */
|
|
Packit Service |
ada5e0 |
int in_quote = 0;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Skip whitespace up to the next token. */
|
|
Packit Service |
ada5e0 |
while (*cmdline && isspace (*cmdline))
|
|
Packit Service |
ada5e0 |
cmdline ++;
|
|
Packit Service |
ada5e0 |
if (*cmdline == 0)
|
|
Packit Service |
ada5e0 |
break;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
start = cmdline;
|
|
Packit Service |
ada5e0 |
/* Check for quoted argument. */
|
|
Packit Service |
ada5e0 |
in_quote = (*cmdline == '\'' || *cmdline == '"') ? *cmdline : 0;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Skip to end of token; either by whitespace or matching quote. */
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "in_quote %d\n", in_quote);
|
|
Packit Service |
ada5e0 |
while (*cmdline
|
|
Packit Service |
ada5e0 |
&& (!isspace (*cmdline) || in_quote))
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
if (*cmdline == in_quote
|
|
Packit Service |
ada5e0 |
&& cmdline != start)
|
|
Packit Service |
ada5e0 |
in_quote = 0;
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "[%c]%d ", *cmdline, in_quote);
|
|
Packit Service |
ada5e0 |
cmdline ++;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "\n");
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Allocate space for this token and store it in args[]. */
|
|
Packit Service |
ada5e0 |
end = cmdline;
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "start<%s> end<%s>\n", start, end);
|
|
Packit Service |
ada5e0 |
args[ap] = (char *) xmalloc (end - start + 1);
|
|
Packit Service |
ada5e0 |
memcpy (args[ap], start, end - start);
|
|
Packit Service |
ada5e0 |
args[ap][end - start] = 0;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Strip off quotes, if found. */
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "args[%d] = <%s>\n", ap, args[ap]);
|
|
Packit Service |
ada5e0 |
if (args[ap][0] == '\''
|
|
Packit Service |
ada5e0 |
&& args[ap][strlen (args[ap])-1] == '\'')
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
args[ap][strlen (args[ap])-1] = 0;
|
|
Packit Service |
ada5e0 |
args[ap] ++;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
else if (args[ap][0] == '"'
|
|
Packit Service |
ada5e0 |
&& args[ap][strlen (args[ap])-1] == '"')
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
args[ap][strlen (args[ap])-1] = 0;
|
|
Packit Service |
ada5e0 |
args[ap] ++;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Replace positional parameters like $4. */
|
|
Packit Service |
ada5e0 |
else if (args[ap][0] == '$'
|
|
Packit Service |
ada5e0 |
&& isdigit (args[ap][1])
|
|
Packit Service |
ada5e0 |
&& args[ap][2] == 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
int a = args[ap][1] - '1';
|
|
Packit Service |
ada5e0 |
if (0 <= a && a < nargs)
|
|
Packit Service |
ada5e0 |
args[ap] = strdup (iargs[a]);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
ap ++;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (*cmdline == 0)
|
|
Packit Service |
ada5e0 |
break;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Lastly, NULL terminate the array and run it. */
|
|
Packit Service |
ada5e0 |
args[ap] = NULL;
|
|
Packit Service |
ada5e0 |
run_command_array (args);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
/* Run a script by reading lines and passing them to the above
|
|
Packit Service |
ada5e0 |
function. */
|
|
Packit Service |
ada5e0 |
static void
|
|
Packit Service |
ada5e0 |
run_script (const char *filename, const char **args)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
char line[MAX_LINE_LENGTH + 1];
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "run_script starting: '%s'\n", filename);
|
|
Packit Service |
ada5e0 |
FILE *f = fopen (filename, "r");
|
|
Packit Service |
ada5e0 |
if (f == NULL)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
fprintf (stderr, "sh: %s: %s\n", filename, strerror (errno));
|
|
Packit Service |
ada5e0 |
exit (1);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
while (fgets (line, sizeof (line), f) != NULL)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
if (line[0] == '#')
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "comment: %s\n", line);
|
|
Packit Service |
ada5e0 |
continue;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
run_command_string (line, args);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
fclose (f);
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
int
|
|
Packit Service |
ada5e0 |
main (int argc, const char **argv)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
int i;
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[1], "--debug") == 0)
|
|
Packit Service |
ada5e0 |
{
|
|
Packit Service |
ada5e0 |
debug_mode = 1;
|
|
Packit Service |
ada5e0 |
--argc;
|
|
Packit Service |
ada5e0 |
++argv;
|
|
Packit Service |
ada5e0 |
}
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "container-sh starting:\n");
|
|
Packit Service |
ada5e0 |
for (i = 0; i < argc; i++)
|
|
Packit Service |
ada5e0 |
dprintf (stderr, " argv[%d] is `%s'\n", i, argv[i]);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
if (strcmp (argv[1], "-c") == 0)
|
|
Packit Service |
ada5e0 |
run_command_string (argv[2], argv+3);
|
|
Packit Service |
ada5e0 |
else
|
|
Packit Service |
ada5e0 |
run_script (argv[1], argv+2);
|
|
Packit Service |
ada5e0 |
|
|
Packit Service |
ada5e0 |
dprintf (stderr, "normal exit 0\n");
|
|
Packit Service |
ada5e0 |
return 0;
|
|
Packit Service |
ada5e0 |
}
|