]> cygwin.com Git - cygwin-apps/setup.git/blob - io_stream.cc
2002-02-19 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / io_stream.cc
1 /*
2 * Copyright (c) 2001, Robert Collins.
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 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16 /* this is the parent class for all IO operations. It's flexable enough to be cover for
17 * HTTP access, local file access, and files being extracted from archives.
18 * It also encapsulates the idea of an archive, and all non-archives become the special
19 * case.
20 */
21
22 #if 0
23 static const char *cvsid =
24 "\n%%% $Id$\n";
25 #endif
26
27 #include "win32.h"
28 #include <stdio.h>
29 #include "log.h"
30 #include "port.h"
31
32 #include "io_stream.h"
33 #include "io_stream_file.h"
34 #include "io_stream_cygfile.h"
35 #include "mkdir.h"
36 #include "String++.h"
37
38 /* Static members */
39 io_stream *
40 io_stream::factory (io_stream * parent)
41 {
42 /* something like,
43 * if !next_file_name
44 * return NULL
45 * switch (magic_id(peek (parent), max_magic_length))
46 * case io_stream * foo = new tar
47 * case io_stream * foo = new bz2
48 * return foo
49 */
50 log (LOG_TIMESTAMP, "io_stream::factory has been called");
51 return NULL;
52 }
53
54 io_stream *
55 io_stream::open (String const &name, String const &mode)
56 {
57 if (name.size() < 7 ||
58 mode.size() == 0)
59 return NULL;
60 /* iterate through the known url prefix's */
61 if (!name.casecompare ("file://", 7))
62 {
63 io_stream_file *rv = new io_stream_file (&name.cstr_oneuse()[7], mode.cstr_oneuse());
64 if (!rv->error ())
65 return rv;
66 delete rv;
67 return NULL;
68 }
69 if (!name.casecompare ("cygfile://", 10))
70 {
71 io_stream_cygfile *rv = new io_stream_cygfile (&name.cstr_oneuse()[10], mode.cstr_oneuse());
72 if (!rv->error ())
73 return rv;
74 delete rv;
75 return NULL;
76 }
77 return NULL;
78 }
79
80 int
81 io_stream::mkpath_p (path_type_t isadir, String const &name)
82 {
83 if (name.size() < 7)
84 return 1;
85 /* iterate through the known url prefix's */
86 if (!name.casecompare ("file://", 7))
87 {
88 return mkdir_p (isadir == PATH_TO_DIR ? 1 : 0, &name.cstr_oneuse()[7]);
89 }
90 if (!name.casecompare ("cygfile://", 10))
91 {
92 return cygmkdir_p (isadir, &name.cstr_oneuse()[10]);
93 }
94 return 1;
95 }
96
97 /* remove a file or directory. */
98 int
99 io_stream::remove (String const &name)
100 {
101 if (!name.size())
102 return 1;
103 /* iterate through the known url prefix's */
104 if (!name.casecompare ("file://", 7))
105 return io_stream_file::remove (&name.cstr_oneuse()[7]);
106 if (!name.casecompare ("cygfile://", 10))
107 return io_stream_cygfile::remove (&name.cstr_oneuse()[10]);
108 return 1;
109 }
110
111 int
112 io_stream::mklink (String const &from, String const &to,
113 io_stream_link_t linktype)
114 {
115 log (LOG_BABBLE, String("io_stream::mklink (") + from + "->" + to + ")");
116 if (!from.size() || !to.size())
117 {
118 log (LOG_TIMESTAMP, "invalid string in from or to parameters to mklink");
119 return 1;
120 }
121 /* iterate through the known url prefixes */
122 if (!from.casecompare ("file://", 7))
123 {
124 /* file urls can symlink or hardlink to file url's. */
125 /* TODO: allow linking to cygfile url's */
126 if (!to.casecompare ("file://", 7))
127 return io_stream_file::mklink (&from.cstr_oneuse()[7], &to.cstr_oneuse()[7], linktype);
128 log (LOG_TIMESTAMP, "Attempt to link across url providers");
129 return 1;
130 }
131 if (!from.casecompare ("cygfile://", 10))
132 {
133 /* cygfile urls can symlink or hardlink to cygfile urls's. */
134 /* TODO: allow -> file urls */
135 if (!to.casecompare ("cygfile://", 10))
136 return io_stream_cygfile::mklink (&from.cstr_oneuse()[10], &to.cstr_oneuse()[10], linktype);
137 log (LOG_TIMESTAMP, "Attempt to link across url providers");
138 return 1;
139 }
140 #if 0
141 if (!strmcasecmp ("http://", from, 7))
142 {
143 /* http urls can symlink to http or ftp url's */
144 }
145 #endif
146 log (LOG_TIMESTAMP, String ("Unsupported url providers for ") + from);
147 return 1;
148 }
149
150 int
151 io_stream::move_copy (String const &from, String const &to)
152 {
153 /* parameters are ok - checked before calling us, and we are private */
154 io_stream *in = io_stream::open (to, "wb");
155 io_stream *out = io_stream::open (from, "rb");
156 if (io_stream::copy (in, out))
157 {
158 log (LOG_TIMESTAMP, String("Failed copy of ") + from + " to "+ to);
159 delete out;
160 io_stream::remove (to);
161 delete in;
162 return 1;
163 }
164 /* TODO:
165 out->set_mtime (in->get_mtime ());
166 */
167 delete in;
168 delete out;
169 io_stream::remove (from);
170 return 0;
171 }
172
173 ssize_t io_stream::copy (io_stream * in, io_stream * out)
174 {
175 if (!in || !out)
176 return -1;
177 char
178 buffer[16384];
179 ssize_t
180 countin,
181 countout;
182 while ((countin = in->read (buffer, 16384)) > 0)
183 {
184 countout = out->write (buffer, countin);
185 if (countout != countin)
186 {
187 log (LOG_TIMESTAMP, "io_stream::copy failed to write %ld bytes",
188 countin);
189 return countout ? countout : -1;
190 }
191 }
192 // XXX FIXME: What if countin < 0? return an error
193
194 /* TODO:
195 out->set_mtime (in->get_mtime ());
196 */
197 return 0;
198 }
199
200 int
201 io_stream::move (String const &from, String const &to)
202 {
203 if (!from.size() || !to.size())
204 {
205 log (LOG_TIMESTAMP, "invalid string in from or to parameters to move");
206 return 1;
207 }
208 /* iterate through the known url prefixes */
209 if (!from.casecompare ("file://", 7))
210 {
211 /* TODO: allow 'move' to cygfile url's */
212 if (to.casecompare ("file://", 7))
213 return io_stream::move_copy (from, to);
214 return io_stream_file::move (&from.cstr_oneuse()[7], &to.cstr_oneuse()[7]);
215 }
216 if (!from.casecompare ("cygfile://", 10))
217 {
218 /* TODO: allow -> file urls */
219 if (to.casecompare ("cygfile://", 10))
220 return io_stream::move_copy (from, to);
221 return io_stream_cygfile::move (&from.cstr_oneuse()[10], &to.cstr_oneuse()[10]);
222 }
223 #if 0
224 if (!strmcasecmp ("http://", from, 7))
225 {
226 /* http urls can symlink to http or ftp url's */
227 }
228 #endif
229 log (LOG_TIMESTAMP, String ("Unsupported url providers for ") + from);
230 return 1;
231 }
232
233 char *
234 io_stream::gets (char *buffer, size_t length)
235 {
236 char *pos = buffer;
237 size_t count = 0;
238 while (count + 1 < length && read (pos, 1) == 1)
239 {
240 count++;
241 pos++;
242 if (*(pos - 1) == '\n')
243 {
244 --pos; /* end of line, remove from buffer */
245 if (pos > buffer && *(pos - 1) == '\r')
246 --pos;
247 break;
248 }
249 }
250 if (count == 0 || error ())
251 /* EOF when no chars found, or an error */
252 return NULL;
253 *pos = '\0';
254 return buffer;
255 }
256
257 int
258 io_stream::exists (String const &name)
259 {
260 if (!name.size())
261 return 1;
262 /* iterate through the known url prefix's */
263 if (!name.casecompare ("file://", 7))
264 return io_stream_file::exists (&name.cstr_oneuse()[7]);
265 if (!name.casecompare ("cygfile://", 10))
266 return io_stream_cygfile::exists (&name.cstr_oneuse()[10]);
267 return 1;
268 }
269
270 /* virtual members */
271
272 io_stream::~io_stream ()
273 {
274 if (!destroyed)
275 log (LOG_TIMESTAMP, "io_stream::~io_stream: It looks like a class hasn't overriden the destructor!");
276 return;
277 }
This page took 0.053301 seconds and 5 git commands to generate.