uronode/extcmd.c

204 lines
4.6 KiB
C
Raw Normal View History

2015-09-03 20:01:45 +01:00
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netax25/ax25.h>
#include <netrose/rose.h>
#include <grp.h>
#include <sys/wait.h>
#include <netax25/axlib.h>
#include <netax25/axconfig.h>
#include "node.h"
#define ECMD_PIPE 1 /* Run through pipe */
#ifdef HAVEMOTD
#define ECMD_RECONN 2 /* */
#endif
static int norm_extcmd(struct cmd *cmdp, char **argv)
{
int pid;
alarm(0L);
pid = fork();
if (pid == -1) {
/* fork error */
node_perror("norm_extcmd: fork", errno);
return 0;
}
if (pid == 0) {
/* child */
setgroups(0, NULL);
setgid(cmdp->gid);
setuid(cmdp->uid);
execve(cmdp->path, argv, NULL);
node_perror("norm_extcmd: execve", errno);
exit(1);
}
/* parent */
waitpid(pid, NULL, 0);
return 0;
}
static int pipe_extcmd(struct cmd *cmdp, char **argv)
{
ax25io *iop;
int pipe_in[2], pipe_out[2];
int pid, c;
fd_set fdset;
if (pipe(pipe_in) == -1) {
node_perror("pipe_extcmd: pipe_in", errno);
return 0;
}
if (pipe(pipe_out) == -1) {
node_perror("pipe_extcmd: pipe_out", errno);
return 0;
}
signal(SIGCHLD, SIG_IGN);
pid = fork();
if (pid == -1) {
/* fork error */
node_perror("pipe_extcmd: fork", errno);
signal(SIGCHLD, SIG_DFL);
return 0;
}
if (pid == 0) {
/* child */
/*
* Redirect childs output to the pipes closing
* stdin/out/err as we go.
*/
dup2(pipe_in[0], STDIN_FILENO);
dup2(pipe_out[1], STDOUT_FILENO);
dup2(pipe_out[1], STDERR_FILENO);
/* Close the other ends */
close(pipe_in[1]);
close(pipe_out[0]);
setgroups(0, NULL);
setgid(cmdp->gid);
setuid(cmdp->uid);
execve(cmdp->path, argv, NULL);
perror("pipe_extcmd: execve");
exit(1);
}
/* parent */
close(pipe_in[0]);
close(pipe_out[1]);
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1 ||
fcntl(pipe_out[0], F_SETFL, O_NONBLOCK) == -1) {
node_perror("pipe_extcmd: fcntl - pipe_out", errno);
goto end;
}
iop = axio_init(pipe_out[0], pipe_in[1], 1024, UNSPEC_EOL);
if (iop == NULL) {
node_perror("pipe_extcmd: Error initializing I/O", -1);
goto end;
}
while (1) {
FD_ZERO(&fdset);
FD_SET(STDIN_FILENO, &fdset);
FD_SET(pipe_out[0], &fdset);
if (select(32, &fdset, 0, 0, 0) == -1) {
node_perror("pipe_extcmd: select", errno);
break;
}
if (FD_ISSET(STDIN_FILENO, &fdset)) {
alarm(ConnTimeout);
while((c = axio_getc(NodeIo)) != -1)
axio_putc(c, iop);
if (errno != EAGAIN)
break;
}
if (FD_ISSET(pipe_out[0], &fdset)) {
alarm(ConnTimeout);
while((c = axio_getc(iop)) != -1)
axio_putc(c, NodeIo);
if (errno != EAGAIN) {
if (errno)
node_msg("%s", strerror(errno));
break;
}
}
axio_flush(NodeIo);
axio_flush(iop);
}
#ifdef HAVEMOTD
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} ", NodeId);
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;31mWelcome back.\e[0m");
} else {
axio_printf(NodeIo, "Welcome back.");
}
} else if (User.ul_type == AF_INET) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo, "\e[01;31m");
}
axio_printf(NodeIo, "Returning you to the shell... ");
} else if (User.ul_type == AF_AX25) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;31m");
}
axio_printf(NodeIo,"Welcome back to %s.", FlexId);
} else if (User.ul_type == AF_ROSE) {
if (check_perms(PERM_ANSI, 0L) != -1) {
axio_printf(NodeIo,"\e[01;31m");
}
axio_printf(NodeIo,"Back to %s", RoseId);
}
#endif
axio_end(iop);
end:
signal(SIGCHLD, SIG_DFL);
kill(pid, SIGKILL);
close(pipe_in[1]);
close(pipe_out[0]);
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
node_perror("pipe_extcmd: fcntl - stdin", errno);
return 0;
}
int extcmd(struct cmd *cmdp, char **argv)
{
int ret;
User.state = STATE_EXTCMD;
User.dl_type = AF_UNSPEC;
strcpy(User.dl_name, cmdp->name);
strupr(User.dl_name);
update_user();
if (cmdp->flags & ECMD_PIPE)
ret = pipe_extcmd(cmdp, argv);
else
ret = norm_extcmd(cmdp, argv);
#ifdef HAVEMOTD
if (cmdp->flags & ECMD_RECONN) {
if (User.ul_type == AF_NETROM) {
axio_printf(NodeIo, "%s} Welcome back.", NodeId);
}
}
else if (User.ul_type == AF_AX25) {
/* axio_printf(NodeIo, "Welcome back to %s.", FlexId); */
}
if (User.ul_type == AF_NETROM) {
node_msg("");
}
#else
if (cmdp->flags)
node_logout("");
#endif
return ret;
}