2 * Copyright (c) 2001, Robert Collins.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
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
23 static const char *cvsid
=
32 #include "io_stream.h"
33 #include "io_stream_file.h"
34 #include "io_stream_cygfile.h"
40 io_stream::factory (io_stream
* parent
)
45 * switch (magic_id(peek (parent), max_magic_length))
46 * case io_stream * foo = new tar
47 * case io_stream * foo = new bz2
50 log (LOG_TIMESTAMP
, "io_stream::factory has been called");
55 io_stream::open (String
const &name
, String
const &mode
)
57 if (name
.size() < 7 ||
60 /* iterate through the known url prefix's */
61 if (!name
.casecompare ("file://", 7))
63 io_stream_file
*rv
= new io_stream_file (&name
.cstr_oneuse()[7], mode
.cstr_oneuse());
69 if (!name
.casecompare ("cygfile://", 10))
71 io_stream_cygfile
*rv
= new io_stream_cygfile (&name
.cstr_oneuse()[10], mode
.cstr_oneuse());
81 io_stream::mkpath_p (path_type_t isadir
, String
const &name
)
85 /* iterate through the known url prefix's */
86 if (!name
.casecompare ("file://", 7))
88 return mkdir_p (isadir
== PATH_TO_DIR
? 1 : 0, &name
.cstr_oneuse()[7]);
90 if (!name
.casecompare ("cygfile://", 10))
92 return cygmkdir_p (isadir
, &name
.cstr_oneuse()[10]);
97 /* remove a file or directory. */
99 io_stream::remove (String
const &name
)
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]);
112 io_stream::mklink (String
const &from
, String
const &to
,
113 io_stream_link_t linktype
)
115 log (LOG_BABBLE
, String("io_stream::mklink (") + from
+ "->" + to
+ ")");
116 if (!from
.size() || !to
.size())
118 log (LOG_TIMESTAMP
, "invalid string in from or to parameters to mklink");
121 /* iterate through the known url prefixes */
122 if (!from
.casecompare ("file://", 7))
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");
131 if (!from
.casecompare ("cygfile://", 10))
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");
141 if (!strmcasecmp ("http://", from
, 7))
143 /* http urls can symlink to http or ftp url's */
146 log (LOG_TIMESTAMP
, String ("Unsupported url providers for ") + from
);
151 io_stream::move_copy (String
const &from
, String
const &to
)
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
))
158 log (LOG_TIMESTAMP
, String("Failed copy of ") + from
+ " to "+ to
);
160 io_stream::remove (to
);
165 out->set_mtime (in->get_mtime ());
169 io_stream::remove (from
);
173 ssize_t
io_stream::copy (io_stream
* in
, io_stream
* out
)
182 while ((countin
= in
->read (buffer
, 16384)) > 0)
184 countout
= out
->write (buffer
, countin
);
185 if (countout
!= countin
)
187 log (LOG_TIMESTAMP
, "io_stream::copy failed to write %ld bytes",
189 return countout
? countout
: -1;
192 // XXX FIXME: What if countin < 0? return an error
195 out->set_mtime (in->get_mtime ());
201 io_stream::move (String
const &from
, String
const &to
)
203 if (!from
.size() || !to
.size())
205 log (LOG_TIMESTAMP
, "invalid string in from or to parameters to move");
208 /* iterate through the known url prefixes */
209 if (!from
.casecompare ("file://", 7))
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]);
216 if (!from
.casecompare ("cygfile://", 10))
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]);
224 if (!strmcasecmp ("http://", from
, 7))
226 /* http urls can symlink to http or ftp url's */
229 log (LOG_TIMESTAMP
, String ("Unsupported url providers for ") + from
);
234 io_stream::gets (char *buffer
, size_t length
)
238 while (count
+ 1 < length
&& read (pos
, 1) == 1)
242 if (*(pos
- 1) == '\n')
244 --pos
; /* end of line, remove from buffer */
245 if (pos
> buffer
&& *(pos
- 1) == '\r')
250 if (count
== 0 || error ())
251 /* EOF when no chars found, or an error */
258 io_stream::exists (String
const &name
)
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]);
270 /* virtual members */
272 io_stream::~io_stream ()
275 log (LOG_TIMESTAMP
, "io_stream::~io_stream: It looks like a class hasn't overriden the destructor!");