]> cygwin.com Git - cygwin-apps/setup.git/blob - io_stream_cygfile.cc
2002-02-19 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / io_stream_cygfile.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 #if 0
17 static const char *cvsid =
18 "\n%%% $Id$\n";
19 #endif
20
21
22 #include "win32.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include "log.h"
27 #include "port.h"
28 #include "mount.h"
29 #include "mkdir.h"
30 #include "mklink2.h"
31 #include <unistd.h>
32 #include "filemanip.h"
33
34 #include "io_stream.h"
35 #include "io_stream_cygfile.h"
36
37 /* For set mtime */
38 #define FACTOR (0x19db1ded53ea710LL)
39 #define NSPERSEC 10000000LL
40
41 static void
42 get_root_dir_now ()
43 {
44 if (get_root_dir ().size())
45 return;
46 read_mounts ();
47 }
48
49 io_stream_cygfile::io_stream_cygfile (String const &name, String const &mode) : fp(), fname()
50 {
51 errno = 0;
52 if (!name.size() || !mode.size())
53 return;
54
55 /* do this every time because the mount points may change due to fwd/back button use...
56 * TODO: make this less...manual
57 */
58 get_root_dir_now ();
59 if (!get_root_dir ().size())
60 /* TODO: assign a errno for "no mount table :} " */
61 return;
62
63 fname = cygpath (name.cstr_oneuse(), 0);
64 lmode = mode;
65 fp = fopen (fname.cstr_oneuse(), mode.cstr_oneuse());
66 if (!fp)
67 lasterr = errno;
68 }
69
70 io_stream_cygfile::~io_stream_cygfile ()
71 {
72 if (fp)
73 fclose (fp);
74 destroyed = 1;
75 }
76
77 /* Static members */
78 int
79 io_stream_cygfile::exists (String const &path)
80 {
81 get_root_dir_now ();
82 if (get_root_dir ().size() && _access (cygpath (path.cstr_oneuse(), 0).cstr_oneuse(), 0) == 0)
83 return 1;
84 return 0;
85 }
86
87 int
88 io_stream_cygfile::remove (String const &path)
89 {
90 if (!path.size())
91 return 1;
92 get_root_dir_now ();
93 if (!get_root_dir ().size())
94 /* TODO: assign a errno for "no mount table :} " */
95 return 1;
96
97 unsigned long w = GetFileAttributes (cygpath (path.cstr_oneuse(),0).cstr_oneuse());
98 if (w != 0xffffffff && w & FILE_ATTRIBUTE_DIRECTORY)
99 {
100 char tmp[cygpath (path.cstr_oneuse(),0).size() + 10];
101 int i = 0;
102 do
103 {
104 ++i;
105 sprintf (tmp, "%s.old-%d", cygpath (path.cstr_oneuse(),0).cstr_oneuse(), i);
106 }
107 while (GetFileAttributes (tmp) != 0xffffffff);
108 fprintf (stderr, "warning: moving directory \"%s\" out of the way.\n",
109 path.cstr_oneuse());
110 MoveFile (cygpath (path.cstr_oneuse(),0).cstr_oneuse(), tmp);
111 }
112 return !DeleteFileA (cygpath (path.cstr_oneuse(),0).cstr_oneuse());
113 }
114
115 int
116 io_stream_cygfile::mklink (String const &from, String const &to,
117 io_stream_link_t linktype)
118 {
119 if (!from.size() || !to.size())
120 return 1;
121 switch (linktype)
122 {
123 case IO_STREAM_SYMLINK:
124 return mkcygsymlink (cygpath (from.cstr_oneuse(),0).cstr_oneuse(), to.cstr_oneuse());
125 case IO_STREAM_HARDLINK:
126 {
127 /* For now, just copy */
128 /* textmode alert: should we translate when linking from an binmode to a
129 text mode mount and vice verca?
130 */
131 io_stream *in = io_stream::open (cygpath (to.cstr_oneuse(),0), "rb");
132 if (!in)
133 {
134 log (LOG_TIMESTAMP, String("could not open ") + to +" for reading in mklink");
135 return 1;
136 }
137 io_stream *out = io_stream::open (cygpath (from.cstr_oneuse(),0), "wb");
138 if (!out)
139 {
140 log (LOG_TIMESTAMP, String("could not open ")+ from + " for writing in mklink");
141 delete in;
142 return 1;
143 }
144
145 if (io_stream::copy (in, out))
146 {
147 log (LOG_TIMESTAMP, String ("Failed to hardlink ")+ from + "->" +to +
148 " during file copy.");
149 delete in;
150 delete out;
151 return 1;
152 }
153 delete in;
154 delete out;
155 return 0;
156 }
157 }
158 return 1;
159 }
160
161
162 /* virtuals */
163
164 ssize_t
165 io_stream_cygfile::read (void *buffer, size_t len)
166 {
167 if (fp)
168 return fread (buffer, 1, len, fp);
169 return 0;
170 }
171
172 ssize_t
173 io_stream_cygfile::write (const void *buffer, size_t len)
174 {
175 if (fp)
176 return fwrite (buffer, 1, len, fp);
177 return 0;
178 }
179
180 ssize_t
181 io_stream_cygfile::peek (void *buffer, size_t len)
182 {
183 log (LOG_TIMESTAMP, "io_stream_cygfile::peek called");
184 if (fp)
185 {
186 int pos = ftell (fp);
187 ssize_t rv = fread (buffer, 1, len, fp);
188 fseek (fp, pos, SEEK_SET);
189 return rv;
190 }
191 return 0;
192 }
193
194 long
195 io_stream_cygfile::tell ()
196 {
197 if (fp)
198 {
199 return ftell (fp);
200 }
201 return 0;
202 }
203
204 int
205 io_stream_cygfile::seek (long where, io_stream_seek_t whence)
206 {
207 if (fp)
208 {
209 return fseek (fp, where, (int) whence);
210 }
211 lasterr = EBADF;
212 return -1;
213 }
214
215 int
216 io_stream_cygfile::error ()
217 {
218 if (fp)
219 return ferror (fp);
220 return lasterr;
221 }
222
223 int
224 cygmkdir_p (enum path_type_t isadir, String const &name)
225 {
226 if (!name.size())
227 return 1;
228 get_root_dir_now ();
229 if (!get_root_dir ().size())
230 /* TODO: assign a errno for "no mount table :} " */
231 return 1;
232 return mkdir_p (isadir == PATH_TO_DIR ? 1 : 0, cygpath (name.cstr_oneuse(),0).cstr_oneuse());
233 }
234
235 int
236 io_stream_cygfile::set_mtime (int mtime)
237 {
238 if (!fname.size())
239 return 1;
240 if (fp)
241 fclose (fp);
242 long long ftimev = mtime * NSPERSEC + FACTOR;
243 FILETIME ftime;
244 ftime.dwHighDateTime = ftimev >> 32;
245 ftime.dwLowDateTime = ftimev;
246 HANDLE h =
247 CreateFileA (fname.cstr_oneuse(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
248 0, OPEN_EXISTING,
249 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
250 if (h)
251 {
252 SetFileTime (h, 0, 0, &ftime);
253 CloseHandle (h);
254 #if 0
255 fp = fopen (fname, lmode);
256 if (!fp)
257 lasterr = errno;
258 #endif
259 return 0;
260 }
261 #if 0
262 // this results in truncated files.
263 // also, semantically, it's nonsense, you cannot write to a file after setting the
264 // mtime without changing the mtime
265 fp = fopen (fname, lmode);
266 if (!fp)
267 lasterr = errno;
268 #endif
269 return 1;
270 }
271
272 int
273 io_stream_cygfile::move (String const &from, String const &to)
274 {
275 if (!from.size() || !to.size())
276 return 1;
277 get_root_dir_now ();
278 if (!get_root_dir ().size())
279 /* TODO: assign a errno for "no mount table :} " */
280 return 1;
281 return rename (cygpath (from.cstr_oneuse(),0).cstr_oneuse(), cygpath (to.cstr_oneuse(),0).cstr_oneuse());
282 }
283
284 size_t
285 io_stream_cygfile::get_size ()
286 {
287 if (!fname.size() )
288 return 0;
289 return get_file_size (fname);
290 }
This page took 0.050222 seconds and 5 git commands to generate.