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