/*
 * Do filename expansion with the shell.
 */

#define EXPAND_BUF	2048

#include "sysincludes.h"
#include "mtools.h"


int safePopenOut(char **command, char *output, int len)
{
	int pipefd[2];
	pid_t pid;
	int status;
	int last;

	if(pipe(pipefd)) {
		return -2;
	}
	switch((pid=fork())){
		case -1:
			return -2;
		case 0: /* the son */
			close(pipefd[0]);
			destroy_privs();
			close(1);
			close(2); /* avoid nasty error messages on stderr */
			dup(pipefd[1]);
			close(pipefd[1]);
			execvp(command[0], command+1);
			exit(1);
		default:
			close(pipefd[1]);
			break;
	}
	last=read(pipefd[0], output, len);
	kill(pid,9);
	wait(&status);
	if(last<0) {
		return -1;
	}
	return last;
}



#ifdef __VMS

/* 2006-04-18 SMS.
   VMS can not do wildcard expansion using a UNIX shell, and some simple
   VMS file specifications look like wildcards by this criterion, so
   it's safer simply to return the argument.  Actual VMS wildcard
   expansion could be implemented if there's ever a reason for it.
*/

const char *expand(const char *input, char *ans)
{
	ans[EXPAND_BUF-1]='\0';

	if (input == NULL)
		return(NULL);
	if (*input == '\0')
		return("");

	strncpy(ans, input, EXPAND_BUF-1);
	return(ans);
}

#else /* def __VMS */

const char *expand(const char *input, char *ans)
{
	int last;
	char buf[256];
	char *command[] = { "/bin/sh", "sh", "-c", 0, 0 };

	ans[EXPAND_BUF-1]='\0';

	if (input == NULL)
		return(NULL);
	if (*input == '\0')
		return("");
					/* any thing to expand? */
	if (!strpbrk(input, "$*(){}[]\\?`~")) {
		strncpy(ans, input, EXPAND_BUF-1);
		return(ans);
	}
					/* popen an echo */
#ifdef HAVE_SNPRINTF
	snprintf(buf, 255, "echo %s", input);
#else
	sprintf(buf, "echo %s", input);
#endif

	command[3]=buf;
	last=safePopenOut(command, ans, EXPAND_BUF-1);
	if(last<0) {
		perror("Pipe read error");
		exit(1);
	}
	if(last)
		ans[last-1] = '\0';
	else
		strncpy(ans, input, EXPAND_BUF-1);
	return ans;
}

#endif /* def __VMS */
