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