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>
17 static const char *cvsid
=
21 #include "io_stream_rsync.h"
22 #include "IOStreamProvider.h"
23 #include "rsync/rsync.h"
26 /* completely private iostream registration class */
27 class RSyncProvider
: public IOStreamProvider
30 int exists (String
const &path
) const
32 return io_stream_rsync::exists(path
);
34 int remove (String
const &path
) const
36 /* Not currently supported */
39 int mklink (String
const &a
, String
const &b
, io_stream_link_t c
) const
41 return io_stream_rsync::mklink(a
,b
,c
);
43 io_stream
*open (String
const &a
,String
const &b
) const
45 return new io_stream_rsync (a
, b
);
48 int move (String
const &a
,String
const &b
) const
50 /* Not supported yet */
53 int mkdir_p (enum path_type_t isadir
, String
const &path
) const
55 /* Not supported yet */
59 RSyncProvider() // no creating this
61 io_stream::registerProvider (theInstance
, "rsync://");
63 RSyncProvider(RSyncProvider
const &); // no copying
64 RSyncProvider
&operator=(RSyncProvider
const &); // no assignment
66 static RSyncProvider theInstance
;
68 RSyncProvider
RSyncProvider::theInstance
= RSyncProvider();
70 io_stream_rsync::io_stream_rsync (String
const &name
, String
const &mode
):
71 fp(), fname(name
),lmode (mode
)
74 if (!name
.size() || !mode
.size())
76 fp
= fopen (name
.cstr_oneuse(), mode
.cstr_oneuse());
81 io_stream_rsync::~io_stream_rsync ()
89 io_stream_rsync::exists (String
const &path
)
91 #if defined(WIN32) && !defined (_CYGWIN_)
92 if (_access (path
.cstr_oneuse(), 0) == 0)
94 if (access (path
.cstr_oneuse(), F_OK
) == 0)
101 io_stream_rsync::remove (String
const &path
)
105 #if defined(WIN32) && !defined (_CYGWIN_)
106 unsigned long w
= GetFileAttributes (path
.cstr_oneuse());
107 if (w
!= 0xffffffff && w
& FILE_ATTRIBUTE_DIRECTORY
)
109 char *tmp
= new char [path
.size() + 10];
114 sprintf (tmp
, "%s.old-%d", path
.cstr_oneuse(), i
);
116 while (GetFileAttributes (tmp
) != 0xffffffff);
117 fprintf (stderr
, "warning: moving directory \"%s\" out of the way.\n",
119 MoveFile (path
.cstr_oneuse(), tmp
);
122 return !DeleteFileA (path
.cstr_oneuse());
124 // FIXME: try rmdir if unlink fails - remove the dir
125 return unlink (path
.cstr_oneuse());
130 io_stream_rsync::mklink (String
const &from
, String
const &to
,
131 io_stream_link_t linktype
)
133 if (!from
.size() || !to
.size())
135 #if defined(WIN32) && !defined (_CYGWIN_)
138 case IO_STREAM_SYMLINK
:
139 return mkcygsymlink (from
.cstr_oneuse(), to
.cstr_oneuse());
140 case IO_STREAM_HARDLINK
:
146 case IO_STREAM_SYMLINK
:
147 return symlink (to
.cstr_oneuse(), from
.cstr_oneuse());
148 case IO_STREAM_HARDLINK
:
149 return link (to
.cstr_oneuse(), from
.cstr_oneuse());
159 io_stream_rsync::read (void *buffer
, size_t len
)
162 return fread (buffer
, 1, len
, fp
);
167 io_stream_rsync::write (const void *buffer
, size_t len
)
170 return fwrite (buffer
, 1, len
, fp
);
175 io_stream_rsync::peek (void *buffer
, size_t len
)
179 int pos
= ftell (fp
);
180 ssize_t rv
= fread (buffer
, 1, len
, fp
);
181 fseek (fp
, pos
, SEEK_SET
);
188 io_stream_rsync::tell ()
198 io_stream_rsync::seek (long where
, io_stream_seek_t whence
)
202 return fseek (fp
, where
, (int) whence
);
209 io_stream_rsync::error ()
217 io_stream_rsync::set_mtime (int mtime
)
223 #if defined(WIN32) && !defined (_CYGWIN_)
224 long long ftimev
= mtime
* NSPERSEC
+ FACTOR
;
226 ftime
.dwHighDateTime
= ftimev
>> 32;
227 ftime
.dwLowDateTime
= ftimev
;
229 CreateFileA (fname
.cstr_oneuse(), GENERIC_WRITE
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
231 FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_BACKUP_SEMANTICS
, 0);
234 SetFileTime (h
, 0, 0, &ftime
);
239 throw new runtime_error ("set_mtime not supported on posix yet.");
245 io_stream_rsync::move (String
const &from
, String
const &to
)
247 if (!from
.size()|| !to
.size())
249 return rename (from
.cstr_oneuse(), to
.cstr_oneuse());
253 io_stream_rsync::get_size ()
257 #if defined(WIN32) && !defined (_CYGWIN_)
262 h
= FindFirstFileA (fname
.cstr_oneuse(), &buf
);
263 if (h
!= INVALID_HANDLE_VALUE
)
265 if (buf
.nFileSizeHigh
== 0)
266 ret
= buf
.nFileSizeLow
;
272 if (stat(fname
.cstr_oneuse(), &buf
))
273 throw new runtime_error ("Failed to stat file - has it been deleted?");