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