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