]> cygwin.com Git - cygwin-apps/setup.git/blob - io_stream.cc
2002-05-04 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 "LogSingleton.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" << endLog;
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) << "io_stream::mklink (" << from << "->" << to << ")"
116 << endLog;
117 if (!from.size() || !to.size())
118 {
119 log (LOG_TIMESTAMP) << "invalid string in from or to parameters to mklink"
120 << endLog;
121 return 1;
122 }
123 /* iterate through the known url prefixes */
124 if (!from.casecompare ("file://", 7))
125 {
126 /* file urls can symlink or hardlink to file url's. */
127 /* TODO: allow linking to cygfile url's */
128 if (!to.casecompare ("file://", 7))
129 return io_stream_file::mklink (&from.cstr_oneuse()[7], &to.cstr_oneuse()[7], linktype);
130 log (LOG_TIMESTAMP) << "Attempt to link across url providers" << endLog;
131 return 1;
132 }
133 if (!from.casecompare ("cygfile://", 10))
134 {
135 /* cygfile urls can symlink or hardlink to cygfile urls's. */
136 /* TODO: allow -> file urls */
137 if (!to.casecompare ("cygfile://", 10))
138 return io_stream_cygfile::mklink (&from.cstr_oneuse()[10], &to.cstr_oneuse()[10], linktype);
139 log (LOG_TIMESTAMP) << "Attempt to link across url providers" << endLog;
140 return 1;
141 }
142 #if 0
143 if (!strmcasecmp ("http://", from, 7))
144 {
145 /* http urls can symlink to http or ftp url's */
146 }
147 #endif
148 log (LOG_TIMESTAMP) << "Unsupported url providers for " << from << endLog;
149 return 1;
150 }
151
152 int
153 io_stream::move_copy (String const &from, String const &to)
154 {
155 /* parameters are ok - checked before calling us, and we are private */
156 io_stream *in = io_stream::open (to, "wb");
157 io_stream *out = io_stream::open (from, "rb");
158 if (io_stream::copy (in, out))
159 {
160 log (LOG_TIMESTAMP) << "Failed copy of " << from << " to " << to
161 << endLog;
162 delete out;
163 io_stream::remove (to);
164 delete in;
165 return 1;
166 }
167 /* TODO:
168 out->set_mtime (in->get_mtime ());
169 */
170 delete in;
171 delete out;
172 io_stream::remove (from);
173 return 0;
174 }
175
176 ssize_t io_stream::copy (io_stream * in, io_stream * out)
177 {
178 if (!in || !out)
179 return -1;
180 char
181 buffer[16384];
182 ssize_t
183 countin,
184 countout;
185 while ((countin = in->read (buffer, 16384)) > 0)
186 {
187 countout = out->write (buffer, countin);
188 if (countout != countin)
189 {
190 log (LOG_TIMESTAMP) << "io_stream::copy failed to write "
191 << countin << " bytes" << endLog;
192 return countout ? countout : -1;
193 }
194 }
195 // XXX FIXME: What if countin < 0? return an error
196
197 /* TODO:
198 out->set_mtime (in->get_mtime ());
199 */
200 return 0;
201 }
202
203 int
204 io_stream::move (String const &from, String const &to)
205 {
206 if (!from.size() || !to.size())
207 {
208 log (LOG_TIMESTAMP) << "invalid string in from or to parameters to move"
209 << endLog;
210 return 1;
211 }
212 /* iterate through the known url prefixes */
213 if (!from.casecompare ("file://", 7))
214 {
215 /* TODO: allow 'move' to cygfile url's */
216 if (to.casecompare ("file://", 7))
217 return io_stream::move_copy (from, to);
218 return io_stream_file::move (&from.cstr_oneuse()[7], &to.cstr_oneuse()[7]);
219 }
220 if (!from.casecompare ("cygfile://", 10))
221 {
222 /* TODO: allow -> file urls */
223 if (to.casecompare ("cygfile://", 10))
224 return io_stream::move_copy (from, to);
225 return io_stream_cygfile::move (&from.cstr_oneuse()[10], &to.cstr_oneuse()[10]);
226 }
227 #if 0
228 if (!strmcasecmp ("http://", from, 7))
229 {
230 /* http urls can symlink to http or ftp url's */
231 }
232 #endif
233 log (LOG_TIMESTAMP) << "Unsupported url providers for " << from << endLog;
234 return 1;
235 }
236
237 char *
238 io_stream::gets (char *buffer, size_t length)
239 {
240 char *pos = buffer;
241 size_t count = 0;
242 while (count + 1 < length && read (pos, 1) == 1)
243 {
244 count++;
245 pos++;
246 if (*(pos - 1) == '\n')
247 {
248 --pos; /* end of line, remove from buffer */
249 if (pos > buffer && *(pos - 1) == '\r')
250 --pos;
251 break;
252 }
253 }
254 if (count == 0 || error ())
255 /* EOF when no chars found, or an error */
256 return NULL;
257 *pos = '\0';
258 return buffer;
259 }
260
261 int
262 io_stream::exists (String const &name)
263 {
264 if (!name.size())
265 return 1;
266 /* iterate through the known url prefix's */
267 if (!name.casecompare ("file://", 7))
268 return io_stream_file::exists (&name.cstr_oneuse()[7]);
269 if (!name.casecompare ("cygfile://", 10))
270 return io_stream_cygfile::exists (&name.cstr_oneuse()[10]);
271 return 1;
272 }
273
274 /* virtual members */
275
276 io_stream::~io_stream ()
277 {
278 if (!destroyed)
279 log (LOG_TIMESTAMP) << "io_stream::~io_stream: It looks like a class "
280 << "hasn't overriden the destructor!" << endLog;
281 return;
282 }
This page took 0.046268 seconds and 5 git commands to generate.