1*d5c9a868SElliott Hughes /* Copyright 1986-1992 Emmet P. Gray.
2*d5c9a868SElliott Hughes * Copyright 1996-2002,2007,2009 Alain Knaff.
3*d5c9a868SElliott Hughes * This file is part of mtools.
4*d5c9a868SElliott Hughes *
5*d5c9a868SElliott Hughes * Mtools is free software: you can redistribute it and/or modify
6*d5c9a868SElliott Hughes * it under the terms of the GNU General Public License as published by
7*d5c9a868SElliott Hughes * the Free Software Foundation, either version 3 of the License, or
8*d5c9a868SElliott Hughes * (at your option) any later version.
9*d5c9a868SElliott Hughes *
10*d5c9a868SElliott Hughes * Mtools is distributed in the hope that it will be useful,
11*d5c9a868SElliott Hughes * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*d5c9a868SElliott Hughes * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*d5c9a868SElliott Hughes * GNU General Public License for more details.
14*d5c9a868SElliott Hughes *
15*d5c9a868SElliott Hughes * You should have received a copy of the GNU General Public License
16*d5c9a868SElliott Hughes * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
17*d5c9a868SElliott Hughes *
18*d5c9a868SElliott Hughes * Do filename expansion with the shell.
19*d5c9a868SElliott Hughes */
20*d5c9a868SElliott Hughes
21*d5c9a868SElliott Hughes #include "sysincludes.h"
22*d5c9a868SElliott Hughes #include "mtools.h"
23*d5c9a868SElliott Hughes
24*d5c9a868SElliott Hughes #ifndef OS_mingw32msvc
safePopenOut(const char ** command,char * output,size_t len)25*d5c9a868SElliott Hughes ssize_t safePopenOut(const char **command, char *output, size_t len)
26*d5c9a868SElliott Hughes {
27*d5c9a868SElliott Hughes int pipefd[2];
28*d5c9a868SElliott Hughes pid_t pid;
29*d5c9a868SElliott Hughes int status;
30*d5c9a868SElliott Hughes ssize_t last;
31*d5c9a868SElliott Hughes
32*d5c9a868SElliott Hughes if(pipe(pipefd)) {
33*d5c9a868SElliott Hughes return -2;
34*d5c9a868SElliott Hughes }
35*d5c9a868SElliott Hughes switch((pid=fork())){
36*d5c9a868SElliott Hughes case -1:
37*d5c9a868SElliott Hughes return -2;
38*d5c9a868SElliott Hughes case 0: /* the son */
39*d5c9a868SElliott Hughes close(pipefd[0]);
40*d5c9a868SElliott Hughes destroy_privs();
41*d5c9a868SElliott Hughes close(1);
42*d5c9a868SElliott Hughes close(2); /* avoid nasty error messages on stderr */
43*d5c9a868SElliott Hughes if(dup(pipefd[1]) < 0) {
44*d5c9a868SElliott Hughes perror("Dup error");
45*d5c9a868SElliott Hughes exit(1);
46*d5c9a868SElliott Hughes }
47*d5c9a868SElliott Hughes close(pipefd[1]);
48*d5c9a868SElliott Hughes execvp(command[0], (char**)(command+1));
49*d5c9a868SElliott Hughes exit(1);
50*d5c9a868SElliott Hughes default:
51*d5c9a868SElliott Hughes close(pipefd[1]);
52*d5c9a868SElliott Hughes break;
53*d5c9a868SElliott Hughes }
54*d5c9a868SElliott Hughes last=read(pipefd[0], output, len);
55*d5c9a868SElliott Hughes kill(pid,9);
56*d5c9a868SElliott Hughes wait(&status);
57*d5c9a868SElliott Hughes if(last<0) {
58*d5c9a868SElliott Hughes return -1;
59*d5c9a868SElliott Hughes }
60*d5c9a868SElliott Hughes return last;
61*d5c9a868SElliott Hughes }
62*d5c9a868SElliott Hughes #endif
63*d5c9a868SElliott Hughes
64*d5c9a868SElliott Hughes
expand(const char * input,char * ans)65*d5c9a868SElliott Hughes const char *expand(const char *input, char *ans)
66*d5c9a868SElliott Hughes {
67*d5c9a868SElliott Hughes #ifndef OS_mingw32msvc
68*d5c9a868SElliott Hughes ssize_t last;
69*d5c9a868SElliott Hughes char buf[256];
70*d5c9a868SElliott Hughes const char *command[] = { "/bin/sh", "sh", "-c", 0, 0 };
71*d5c9a868SElliott Hughes
72*d5c9a868SElliott Hughes ans[EXPAND_BUF-1]='\0';
73*d5c9a868SElliott Hughes
74*d5c9a868SElliott Hughes if (input == NULL)
75*d5c9a868SElliott Hughes return(NULL);
76*d5c9a868SElliott Hughes if (*input == '\0')
77*d5c9a868SElliott Hughes return("");
78*d5c9a868SElliott Hughes /* any thing to expand? */
79*d5c9a868SElliott Hughes if (!strpbrk(input, "$*(){}[]\\?`~")) {
80*d5c9a868SElliott Hughes strncpy(ans, input, EXPAND_BUF-1);
81*d5c9a868SElliott Hughes return(ans);
82*d5c9a868SElliott Hughes }
83*d5c9a868SElliott Hughes /* popen an echo */
84*d5c9a868SElliott Hughes #ifdef HAVE_SNPRINTF
85*d5c9a868SElliott Hughes snprintf(buf, 255, "echo %s", input);
86*d5c9a868SElliott Hughes #else
87*d5c9a868SElliott Hughes sprintf(buf, "echo %s", input);
88*d5c9a868SElliott Hughes #endif
89*d5c9a868SElliott Hughes
90*d5c9a868SElliott Hughes command[3]=buf;
91*d5c9a868SElliott Hughes last=safePopenOut(command, ans, EXPAND_BUF-1);
92*d5c9a868SElliott Hughes if(last<0) {
93*d5c9a868SElliott Hughes perror("Pipe read error");
94*d5c9a868SElliott Hughes exit(1);
95*d5c9a868SElliott Hughes }
96*d5c9a868SElliott Hughes if(last)
97*d5c9a868SElliott Hughes ans[last-1] = '\0';
98*d5c9a868SElliott Hughes else
99*d5c9a868SElliott Hughes strncpy(ans, input, EXPAND_BUF-1);
100*d5c9a868SElliott Hughes return ans;
101*d5c9a868SElliott Hughes #else
102*d5c9a868SElliott Hughes strncpy(ans, input, EXPAND_BUF-1);
103*d5c9a868SElliott Hughes ans[EXPAND_BUF-1]='\0';
104*d5c9a868SElliott Hughes return ans;
105*d5c9a868SElliott Hughes #endif
106*d5c9a868SElliott Hughes }
107