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#define EXPAND_BUF 2048 22 23#include "sysincludes.h" 24#include "mtools.h" 25 26#ifndef OS_mingw32msvc 27int safePopenOut(const char **command, char *output, int len) 28{ 29 int pipefd[2]; 30 pid_t pid; 31 int status; 32 int last; 33 34 if(pipe(pipefd)) { 35 return -2; 36 } 37 switch((pid=fork())){ 38 case -1: 39 return -2; 40 case 0: /* the son */ 41 close(pipefd[0]); 42 destroy_privs(); 43 close(1); 44 close(2); /* avoid nasty error messages on stderr */ 45 dup(pipefd[1]); 46 close(pipefd[1]); 47 execvp(command[0], (char**)(command+1)); 48 exit(1); 49 default: 50 close(pipefd[1]); 51 break; 52 } 53 last=read(pipefd[0], output, len); 54 kill(pid,9); 55 wait(&status); 56 if(last<0) { 57 return -1; 58 } 59 return last; 60} 61#endif 62 63 64const char *expand(const char *input, char *ans) 65{ 66#ifndef OS_mingw32msvc 67 int last; 68 char buf[256]; 69 const char *command[] = { "/bin/sh", "sh", "-c", 0, 0 }; 70 71 ans[EXPAND_BUF-1]='\0'; 72 73 if (input == NULL) 74 return(NULL); 75 if (*input == '\0') 76 return(""); 77 /* any thing to expand? */ 78 if (!strpbrk(input, "$*(){}[]\\?`~")) { 79 strncpy(ans, input, EXPAND_BUF-1); 80 return(ans); 81 } 82 /* popen an echo */ 83#ifdef HAVE_SNPRINTF 84 snprintf(buf, 255, "echo %s", input); 85#else 86 sprintf(buf, "echo %s", input); 87#endif 88 89 command[3]=buf; 90 last=safePopenOut(command, ans, EXPAND_BUF-1); 91 if(last<0) { 92 perror("Pipe read error"); 93 exit(1); 94 } 95 if(last) 96 ans[last-1] = '\0'; 97 else 98 strncpy(ans, input, EXPAND_BUF-1); 99 return ans; 100#else 101 strncpy(ans, input, EXPAND_BUF-1); 102 ans[EXPAND_BUF-1]='\0'; 103 return ans; 104#endif 105} 106