Update copyright years.
[midnight-commander.git] / src / vfs / local / local.c
blob2112e1006d92ee31fab59ad2f27cab4db99b48fb
1 /*
2 Virtual File System: local file system.
4 Copyright (C) 1995-2016
5 Free Software Foundation, Inc.
7 This file is part of the Midnight Commander.
9 The Midnight Commander is free software: you can redistribute it
10 and/or modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation, either version 3 of the License,
12 or (at your option) any later version.
14 The Midnight Commander is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /**
24 * \file
25 * \brief Source: local FS
28 #include <config.h>
29 #include <errno.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <stdio.h>
33 #include <string.h>
35 #include "lib/global.h"
37 #include "lib/vfs/utilvfs.h"
39 #include "local.h"
41 /*** global variables ****************************************************************************/
43 /*** file scope macro definitions ****************************************************************/
45 /*** file scope type declarations ****************************************************************/
47 /*** file scope variables ************************************************************************/
49 static struct vfs_class vfs_local_ops;
51 /*** file scope functions ************************************************************************/
52 /* --------------------------------------------------------------------------------------------- */
54 /**
55 * Note: Some of this functions are not static. This has rather good
56 * reason: exactly same functions would have to appear in sfs.c. This
57 * saves both computer's memory and my work. <pavel@ucw.cz>
61 /* --------------------------------------------------------------------------------------------- */
63 static void *
64 local_open (const vfs_path_t * vpath, int flags, mode_t mode)
66 int *local_info;
67 int fd;
68 const vfs_path_element_t *path_element;
70 path_element = vfs_path_get_by_index (vpath, -1);
71 fd = open (path_element->path, NO_LINEAR (flags), mode);
72 if (fd == -1)
73 return 0;
75 local_info = g_new (int, 1);
76 *local_info = fd;
78 return local_info;
81 /* --------------------------------------------------------------------------------------------- */
83 static void *
84 local_opendir (const vfs_path_t * vpath)
86 DIR **local_info;
87 DIR *dir;
88 const vfs_path_element_t *path_element;
90 path_element = vfs_path_get_by_index (vpath, -1);
91 dir = opendir (path_element->path);
92 if (!dir)
93 return 0;
95 local_info = (DIR **) g_new (DIR *, 1);
96 *local_info = dir;
98 return local_info;
101 /* --------------------------------------------------------------------------------------------- */
103 static void *
104 local_readdir (void *data)
106 return readdir (*(DIR **) data);
109 /* --------------------------------------------------------------------------------------------- */
111 static int
112 local_closedir (void *data)
114 int i;
116 i = closedir (*(DIR **) data);
117 g_free (data);
118 return i;
121 /* --------------------------------------------------------------------------------------------- */
123 static int
124 local_stat (const vfs_path_t * vpath, struct stat *buf)
126 const vfs_path_element_t *path_element;
128 path_element = vfs_path_get_by_index (vpath, -1);
129 return stat (path_element->path, buf);
132 /* --------------------------------------------------------------------------------------------- */
134 static int
135 local_lstat (const vfs_path_t * vpath, struct stat *buf)
137 const vfs_path_element_t *path_element;
139 path_element = vfs_path_get_by_index (vpath, -1);
140 #ifndef HAVE_STATLSTAT
141 return lstat (path_element->path, buf);
142 #else
143 return statlstat (path_element->path, buf);
144 #endif
147 /* --------------------------------------------------------------------------------------------- */
149 static int
150 local_chmod (const vfs_path_t * vpath, mode_t mode)
152 const vfs_path_element_t *path_element;
154 path_element = vfs_path_get_by_index (vpath, -1);
155 return chmod (path_element->path, mode);
158 /* --------------------------------------------------------------------------------------------- */
160 static int
161 local_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
163 const vfs_path_element_t *path_element;
165 path_element = vfs_path_get_by_index (vpath, -1);
166 return chown (path_element->path, owner, group);
169 /* --------------------------------------------------------------------------------------------- */
171 static int
172 local_utime (const vfs_path_t * vpath, struct utimbuf *times)
174 const vfs_path_element_t *path_element;
176 path_element = vfs_path_get_by_index (vpath, -1);
177 return utime (path_element->path, times);
180 /* --------------------------------------------------------------------------------------------- */
182 static int
183 local_readlink (const vfs_path_t * vpath, char *buf, size_t size)
185 const vfs_path_element_t *path_element;
187 path_element = vfs_path_get_by_index (vpath, -1);
188 return readlink (path_element->path, buf, size);
191 /* --------------------------------------------------------------------------------------------- */
193 static int
194 local_unlink (const vfs_path_t * vpath)
196 const vfs_path_element_t *path_element;
198 path_element = vfs_path_get_by_index (vpath, -1);
199 return unlink (path_element->path);
202 /* --------------------------------------------------------------------------------------------- */
204 static int
205 local_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
207 const vfs_path_element_t *path_element1;
208 const vfs_path_element_t *path_element2;
210 path_element1 = vfs_path_get_by_index (vpath1, -1);
211 path_element2 = vfs_path_get_by_index (vpath2, -1);
212 return symlink (path_element1->path, path_element2->path);
215 /* --------------------------------------------------------------------------------------------- */
217 static ssize_t
218 local_write (void *data, const char *buf, size_t nbyte)
220 int fd;
221 int n;
223 if (!data)
224 return -1;
226 fd = *(int *) data;
227 while ((n = write (fd, buf, nbyte)) == -1)
229 #ifdef EAGAIN
230 if (errno == EAGAIN)
231 continue;
232 #endif
233 #ifdef EINTR
234 if (errno == EINTR)
235 continue;
236 #endif
237 break;
239 return n;
242 /* --------------------------------------------------------------------------------------------- */
244 static int
245 local_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
247 const vfs_path_element_t *path_element1;
248 const vfs_path_element_t *path_element2;
250 path_element1 = vfs_path_get_by_index (vpath1, -1);
251 path_element2 = vfs_path_get_by_index (vpath2, -1);
252 return rename (path_element1->path, path_element2->path);
255 /* --------------------------------------------------------------------------------------------- */
257 static int
258 local_chdir (const vfs_path_t * vpath)
260 const vfs_path_element_t *path_element;
262 path_element = vfs_path_get_by_index (vpath, -1);
263 return chdir (path_element->path);
266 /* --------------------------------------------------------------------------------------------- */
268 static int
269 local_mknod (const vfs_path_t * vpath, mode_t mode, dev_t dev)
271 const vfs_path_element_t *path_element;
273 path_element = vfs_path_get_by_index (vpath, -1);
274 return mknod (path_element->path, mode, dev);
277 /* --------------------------------------------------------------------------------------------- */
279 static int
280 local_link (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
282 const vfs_path_element_t *path_element1;
283 const vfs_path_element_t *path_element2;
285 path_element1 = vfs_path_get_by_index (vpath1, -1);
286 path_element2 = vfs_path_get_by_index (vpath2, -1);
287 return link (path_element1->path, path_element2->path);
290 /* --------------------------------------------------------------------------------------------- */
292 static int
293 local_mkdir (const vfs_path_t * vpath, mode_t mode)
295 const vfs_path_element_t *path_element;
297 path_element = vfs_path_get_by_index (vpath, -1);
298 return mkdir (path_element->path, mode);
301 /* --------------------------------------------------------------------------------------------- */
303 static int
304 local_rmdir (const vfs_path_t * vpath)
306 const vfs_path_element_t *path_element;
308 path_element = vfs_path_get_by_index (vpath, -1);
309 return rmdir (path_element->path);
312 /* --------------------------------------------------------------------------------------------- */
314 static vfs_path_t *
315 local_getlocalcopy (const vfs_path_t * vpath)
317 return vfs_path_clone (vpath);
320 /* --------------------------------------------------------------------------------------------- */
322 static int
323 local_ungetlocalcopy (const vfs_path_t * vpath, const vfs_path_t * local, gboolean has_changed)
325 (void) vpath;
326 (void) local;
327 (void) has_changed;
329 return 0;
332 /* --------------------------------------------------------------------------------------------- */
334 static int
335 local_which (struct vfs_class *me, const char *path)
337 (void) me;
338 (void) path;
340 return 0; /* Every path which other systems do not like is expected to be ours */
343 /* --------------------------------------------------------------------------------------------- */
344 /*** public functions ****************************************************************************/
345 /* --------------------------------------------------------------------------------------------- */
347 ssize_t
348 local_read (void *data, char *buffer, size_t count)
350 int n;
352 if (!data)
353 return -1;
355 while ((n = read (*((int *) data), buffer, count)) == -1)
357 #ifdef EAGAIN
358 if (errno == EAGAIN)
359 continue;
360 #endif
361 #ifdef EINTR
362 if (errno == EINTR)
363 continue;
364 #endif
365 return -1;
367 return n;
370 /* --------------------------------------------------------------------------------------------- */
373 local_close (void *data)
375 int fd;
377 if (!data)
378 return -1;
380 fd = *(int *) data;
381 g_free (data);
382 return close (fd);
385 /* --------------------------------------------------------------------------------------------- */
388 local_errno (struct vfs_class *me)
390 (void) me;
391 return errno;
394 /* --------------------------------------------------------------------------------------------- */
397 local_fstat (void *data, struct stat *buf)
399 /* FIXME: avoid type cast */
400 return fstat (*((int *) data), buf);
403 /* --------------------------------------------------------------------------------------------- */
405 off_t
406 local_lseek (void *data, off_t offset, int whence)
408 int fd = *(int *) data;
410 return lseek (fd, offset, whence);
413 /* --------------------------------------------------------------------------------------------- */
415 void
416 init_localfs (void)
418 vfs_local_ops.name = "localfs";
419 vfs_local_ops.flags = VFSF_LOCAL;
420 vfs_local_ops.which = local_which;
421 vfs_local_ops.open = local_open;
422 vfs_local_ops.close = local_close;
423 vfs_local_ops.read = local_read;
424 vfs_local_ops.write = local_write;
425 vfs_local_ops.opendir = local_opendir;
426 vfs_local_ops.readdir = local_readdir;
427 vfs_local_ops.closedir = local_closedir;
428 vfs_local_ops.stat = local_stat;
429 vfs_local_ops.lstat = local_lstat;
430 vfs_local_ops.fstat = local_fstat;
431 vfs_local_ops.chmod = local_chmod;
432 vfs_local_ops.chown = local_chown;
433 vfs_local_ops.utime = local_utime;
434 vfs_local_ops.readlink = local_readlink;
435 vfs_local_ops.symlink = local_symlink;
436 vfs_local_ops.link = local_link;
437 vfs_local_ops.unlink = local_unlink;
438 vfs_local_ops.rename = local_rename;
439 vfs_local_ops.chdir = local_chdir;
440 vfs_local_ops.ferrno = local_errno;
441 vfs_local_ops.lseek = local_lseek;
442 vfs_local_ops.mknod = local_mknod;
443 vfs_local_ops.getlocalcopy = local_getlocalcopy;
444 vfs_local_ops.ungetlocalcopy = local_ungetlocalcopy;
445 vfs_local_ops.mkdir = local_mkdir;
446 vfs_local_ops.rmdir = local_rmdir;
447 vfs_register_class (&vfs_local_ops);
450 /* --------------------------------------------------------------------------------------------- */