xref: /aosp_15_r20/external/mtools/expand.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
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