1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif /* HAVE_CONFIG_H */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #ifndef NO_STRING_H
27 #include <string.h>
28 #else
29 #include <strings.h>
30 #endif
31 #include "timidity.h"
32 #include "url.h"
33 
34 #ifdef HAVE_POPEN
35 /* It is not supported command PIPE at Windows */
36 
37 typedef struct _URL_pipe
38 {
39     char common[sizeof(struct _URL)];
40     FILE *fp;
41 } URL_pipe;
42 
43 #define PIPE_FP(url) (((URL_pipe *)(url))->fp)
44 
45 static int name_pipe_check(char *url_string);
46 static long url_pipe_read(URL url, void *buff, long n);
47 static char *url_pipe_gets(URL url, char *buff, int n);
48 static int url_pipe_fgetc(URL url);
49 static void url_pipe_close(URL url);
50 
51 struct URL_module URL_module_pipe =
52 {
53     URL_pipe_t,			/* type */
54     name_pipe_check,		/* URL checker */
55     NULL,			/* initializer */
56     url_pipe_open,		/* open */
57     NULL			/* must be NULL */
58 };
59 
60 /* url_string := "command|" */
name_pipe_check(char * url_string)61 static int name_pipe_check(char *url_string)
62 {
63 #ifdef PIPE_SCHEME_ENABLE
64     char *p;
65     p = strrchr(url_string, '|');
66     if(p == NULL)
67 	return 0;
68     p++;
69     while(*p == ' ')
70 	p++;
71     return *p == '\0';
72 #else
73     return 0;
74 #endif
75 }
76 
url_pipe_open(char * command)77 URL url_pipe_open(char *command)
78 {
79     URL_pipe *url;
80     char buff[BUFSIZ], *p;
81 
82     strncpy(buff, command, sizeof(buff));
83     buff[sizeof(buff) - 1] = '\0';
84     p = strrchr(buff, '|');
85     if(p != NULL)
86     {
87 	char *q;
88 
89 	q = p + 1;
90 	while(*q == ' ')
91 	    q++;
92 	if(*q == '\0')
93 	{
94 	    p--;
95 	    while(buff < p && *p == ' ')
96 		p--;
97 	    if(buff == p)
98 	    {
99 		errno = ENOENT;
100 		url_errno = URLERR_IURLF;
101 		return NULL;
102 	    }
103 	    p[1] = '\0';
104 	}
105     }
106 
107     url = (URL_pipe *)alloc_url(sizeof(URL_pipe));
108     if(url == NULL)
109     {
110 	url_errno = errno;
111 	return NULL;
112     }
113 
114     /* common members */
115     URLm(url, type)      = URL_pipe_t;
116     URLm(url, url_read)  = url_pipe_read;
117     URLm(url, url_gets)  = url_pipe_gets;
118     URLm(url, url_fgetc) = url_pipe_fgetc;
119     URLm(url, url_seek)  = NULL;
120     URLm(url, url_tell)  = NULL;
121     URLm(url, url_close) = url_pipe_close;
122 
123     /* private members */
124     url->fp = NULL;
125 
126     if((url->fp = popen(buff, "r")) == NULL)
127     {
128 	url_pipe_close((URL)url);
129 	url_errno = errno;
130 	return NULL;
131     }
132 
133     return (URL)url;
134 }
135 
url_pipe_read(URL url,void * buff,long n)136 static long url_pipe_read(URL url, void *buff, long n)
137 {
138     return (long)fread(buff, 1, n, PIPE_FP(url));
139 }
140 
url_pipe_gets(URL url,char * buff,int n)141 static char *url_pipe_gets(URL url, char *buff, int n)
142 {
143     return fgets(buff, n, PIPE_FP(url));
144 }
145 
url_pipe_fgetc(URL url)146 static int url_pipe_fgetc(URL url)
147 {
148 #ifdef getc
149     return getc(PIPE_FP(url));
150 #else
151     return fgetc(PIPE_FP(url));
152 #endif /* getc */
153 }
154 
url_pipe_close(URL url)155 static void url_pipe_close(URL url)
156 {
157     int save_errno = errno;
158     if(PIPE_FP(url) != NULL)
159 	pclose(PIPE_FP(url));
160     free(url);
161     errno = save_errno;
162 }
163 
164 #else /* HAVE_POPEN */
165 struct URL_module URL_module_pipe =
166 {
167     URL_none_t,			/* type */
168     NULL,			/* URL checker */
169     NULL,			/* initializer */
170     NULL,			/* open */
171     NULL			/* must be NULL */
172 };
url_pipe_open(char * command)173 URL url_pipe_open(char *command) { return NULL; } /* dmy */
174 #endif
175