root/src/vfs/local/local.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. local_open
  2. local_opendir
  3. local_readdir
  4. local_closedir
  5. local_stat
  6. local_lstat
  7. local_chmod
  8. local_chown
  9. local_utime
  10. local_readlink
  11. local_unlink
  12. local_symlink
  13. local_write
  14. local_rename
  15. local_chdir
  16. local_mknod
  17. local_link
  18. local_mkdir
  19. local_rmdir
  20. local_getlocalcopy
  21. local_ungetlocalcopy
  22. local_which
  23. local_read
  24. local_close
  25. local_errno
  26. local_fstat
  27. local_lseek
  28. local_nothingisopen
  29. vfs_init_localfs

   1 /*
   2    Virtual File System: local file system.
   3 
   4    Copyright (C) 1995-2020
   5    Free Software Foundation, Inc.
   6 
   7    This file is part of the Midnight Commander.
   8 
   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.
  13 
  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.
  18 
  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/>.
  21  */
  22 
  23 /**
  24  * \file
  25  * \brief Source: local FS
  26  */
  27 
  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>
  34 
  35 #include "lib/global.h"
  36 
  37 #include "lib/vfs/xdirentry.h"  /* vfs_s_subclass */
  38 #include "lib/vfs/utilvfs.h"
  39 
  40 #include "local.h"
  41 
  42 /*** global variables ****************************************************************************/
  43 
  44 /*** file scope macro definitions ****************************************************************/
  45 
  46 /*** file scope type declarations ****************************************************************/
  47 
  48 /*** file scope variables ************************************************************************/
  49 
  50 static struct vfs_s_subclass local_subclass;
  51 static struct vfs_class *vfs_local_ops = VFS_CLASS (&local_subclass);
  52 
  53 /* --------------------------------------------------------------------------------------------- */
  54 /*** file scope functions ************************************************************************/
  55 /* --------------------------------------------------------------------------------------------- */
  56 
  57 /**
  58  * Note: Some of this functions are not static. This has rather good
  59  * reason: exactly same functions would have to appear in sfs.c. This
  60  * saves both computer's memory and my work.  <pavel@ucw.cz>
  61  */
  62 
  63 
  64 /* --------------------------------------------------------------------------------------------- */
  65 
  66 static void *
  67 local_open (const vfs_path_t * vpath, int flags, mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help]  */
  68 {
  69     int *local_info;
  70     int fd;
  71     const vfs_path_element_t *path_element;
  72 
  73     path_element = vfs_path_get_by_index (vpath, -1);
  74     fd = open (path_element->path, NO_LINEAR (flags), mode);
  75     if (fd == -1)
  76         return 0;
  77 
  78     local_info = g_new (int, 1);
  79     *local_info = fd;
  80 
  81     return local_info;
  82 }
  83 
  84 /* --------------------------------------------------------------------------------------------- */
  85 
  86 static void *
  87 local_opendir (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
  88 {
  89     DIR **local_info;
  90     DIR *dir = NULL;
  91     const vfs_path_element_t *path_element;
  92 
  93     path_element = vfs_path_get_by_index (vpath, -1);
  94 
  95     /* On Linux >= 5.1, MC sometimes shows empty directpries on mounted CIFS shares.
  96      * Rereading directory restores the directory content.
  97      *
  98      * Reopen directory, if first readdir() returns NULL and errno == EINTR.
  99      */
 100     while (dir == NULL)
 101     {
 102         dir = opendir (path_element->path);
 103         if (dir == NULL)
 104             return NULL;
 105 
 106         if (readdir (dir) == NULL && errno == EINTR)
 107         {
 108             closedir (dir);
 109             dir = NULL;
 110         }
 111         else
 112             rewinddir (dir);
 113     }
 114 
 115     local_info = (DIR **) g_new (DIR *, 1);
 116     *local_info = dir;
 117 
 118     return local_info;
 119 }
 120 
 121 /* --------------------------------------------------------------------------------------------- */
 122 
 123 static struct vfs_dirent *
 124 local_readdir (void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 125 {
 126     struct dirent *d;
 127 
 128     d = readdir (*(DIR **) data);
 129 
 130     return (d != NULL ? vfs_dirent_init (NULL, d->d_name, d->d_ino) : NULL);
 131 }
 132 
 133 /* --------------------------------------------------------------------------------------------- */
 134 
 135 static int
 136 local_closedir (void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 137 {
 138     int i;
 139 
 140     i = closedir (*(DIR **) data);
 141     g_free (data);
 142     return i;
 143 }
 144 
 145 /* --------------------------------------------------------------------------------------------- */
 146 
 147 static int
 148 local_stat (const vfs_path_t * vpath, struct stat *buf)
     /* [previous][next][first][last][top][bottom][index][help]  */
 149 {
 150     const vfs_path_element_t *path_element;
 151 
 152     path_element = vfs_path_get_by_index (vpath, -1);
 153     return stat (path_element->path, buf);
 154 }
 155 
 156 /* --------------------------------------------------------------------------------------------- */
 157 
 158 static int
 159 local_lstat (const vfs_path_t * vpath, struct stat *buf)
     /* [previous][next][first][last][top][bottom][index][help]  */
 160 {
 161     const vfs_path_element_t *path_element;
 162 
 163     path_element = vfs_path_get_by_index (vpath, -1);
 164 #ifndef HAVE_STATLSTAT
 165     return lstat (path_element->path, buf);
 166 #else
 167     return statlstat (path_element->path, buf);
 168 #endif
 169 }
 170 
 171 /* --------------------------------------------------------------------------------------------- */
 172 
 173 static int
 174 local_chmod (const vfs_path_t * vpath, mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help]  */
 175 {
 176     const vfs_path_element_t *path_element;
 177 
 178     path_element = vfs_path_get_by_index (vpath, -1);
 179     return chmod (path_element->path, mode);
 180 }
 181 
 182 /* --------------------------------------------------------------------------------------------- */
 183 
 184 static int
 185 local_chown (const vfs_path_t * vpath, uid_t owner, gid_t group)
     /* [previous][next][first][last][top][bottom][index][help]  */
 186 {
 187     const vfs_path_element_t *path_element;
 188 
 189     path_element = vfs_path_get_by_index (vpath, -1);
 190     return chown (path_element->path, owner, group);
 191 }
 192 
 193 /* --------------------------------------------------------------------------------------------- */
 194 
 195 static int
 196 local_utime (const vfs_path_t * vpath, mc_timesbuf_t * times)
     /* [previous][next][first][last][top][bottom][index][help]  */
 197 {
 198     int ret;
 199     const vfs_path_element_t *path_element;
 200 
 201     path_element = vfs_path_get_by_index (vpath, -1);
 202 #ifdef HAVE_UTIMENSAT
 203     ret = utimensat (AT_FDCWD, path_element->path, *times, 0);
 204 #else
 205     ret = utime (path_element->path, times);
 206 #endif
 207     return ret;
 208 }
 209 
 210 /* --------------------------------------------------------------------------------------------- */
 211 
 212 static int
 213 local_readlink (const vfs_path_t * vpath, char *buf, size_t size)
     /* [previous][next][first][last][top][bottom][index][help]  */
 214 {
 215     const vfs_path_element_t *path_element;
 216 
 217     path_element = vfs_path_get_by_index (vpath, -1);
 218     return readlink (path_element->path, buf, size);
 219 }
 220 
 221 /* --------------------------------------------------------------------------------------------- */
 222 
 223 static int
 224 local_unlink (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 225 {
 226     const vfs_path_element_t *path_element;
 227 
 228     path_element = vfs_path_get_by_index (vpath, -1);
 229     return unlink (path_element->path);
 230 }
 231 
 232 /* --------------------------------------------------------------------------------------------- */
 233 
 234 static int
 235 local_symlink (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 236 {
 237     const vfs_path_element_t *path_element1, *path_element2;
 238 
 239     path_element1 = vfs_path_get_by_index (vpath1, -1);
 240     path_element2 = vfs_path_get_by_index (vpath2, -1);
 241     return symlink (path_element1->path, path_element2->path);
 242 }
 243 
 244 /* --------------------------------------------------------------------------------------------- */
 245 
 246 static ssize_t
 247 local_write (void *data, const char *buf, size_t nbyte)
     /* [previous][next][first][last][top][bottom][index][help]  */
 248 {
 249     int fd;
 250     int n;
 251 
 252     if (data == NULL)
 253         return (-1);
 254 
 255     fd = *(int *) data;
 256 
 257     while ((n = write (fd, buf, nbyte)) == -1)
 258     {
 259 #ifdef EAGAIN
 260         if (errno == EAGAIN)
 261             continue;
 262 #endif
 263 #ifdef EINTR
 264         if (errno == EINTR)
 265             continue;
 266 #endif
 267         break;
 268     }
 269 
 270     return n;
 271 }
 272 
 273 /* --------------------------------------------------------------------------------------------- */
 274 
 275 static int
 276 local_rename (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 277 {
 278     const vfs_path_element_t *path_element1, *path_element2;
 279 
 280     path_element1 = vfs_path_get_by_index (vpath1, -1);
 281     path_element2 = vfs_path_get_by_index (vpath2, -1);
 282     return rename (path_element1->path, path_element2->path);
 283 }
 284 
 285 /* --------------------------------------------------------------------------------------------- */
 286 
 287 static int
 288 local_chdir (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 289 {
 290     const vfs_path_element_t *path_element;
 291 
 292     path_element = vfs_path_get_by_index (vpath, -1);
 293     return chdir (path_element->path);
 294 }
 295 
 296 /* --------------------------------------------------------------------------------------------- */
 297 
 298 static int
 299 local_mknod (const vfs_path_t * vpath, mode_t mode, dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help]  */
 300 {
 301     const vfs_path_element_t *path_element;
 302 
 303     path_element = vfs_path_get_by_index (vpath, -1);
 304     return mknod (path_element->path, mode, dev);
 305 }
 306 
 307 /* --------------------------------------------------------------------------------------------- */
 308 
 309 static int
 310 local_link (const vfs_path_t * vpath1, const vfs_path_t * vpath2)
     /* [previous][next][first][last][top][bottom][index][help]  */
 311 {
 312     const vfs_path_element_t *path_element1, *path_element2;
 313 
 314     path_element1 = vfs_path_get_by_index (vpath1, -1);
 315     path_element2 = vfs_path_get_by_index (vpath2, -1);
 316     return link (path_element1->path, path_element2->path);
 317 }
 318 
 319 /* --------------------------------------------------------------------------------------------- */
 320 
 321 static int
 322 local_mkdir (const vfs_path_t * vpath, mode_t mode)
     /* [previous][next][first][last][top][bottom][index][help]  */
 323 {
 324     const vfs_path_element_t *path_element;
 325 
 326     path_element = vfs_path_get_by_index (vpath, -1);
 327     return mkdir (path_element->path, mode);
 328 }
 329 
 330 /* --------------------------------------------------------------------------------------------- */
 331 
 332 static int
 333 local_rmdir (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 334 {
 335     const vfs_path_element_t *path_element;
 336 
 337     path_element = vfs_path_get_by_index (vpath, -1);
 338     return rmdir (path_element->path);
 339 }
 340 
 341 /* --------------------------------------------------------------------------------------------- */
 342 
 343 static vfs_path_t *
 344 local_getlocalcopy (const vfs_path_t * vpath)
     /* [previous][next][first][last][top][bottom][index][help]  */
 345 {
 346     return vfs_path_clone (vpath);
 347 }
 348 
 349 /* --------------------------------------------------------------------------------------------- */
 350 
 351 static int
 352 local_ungetlocalcopy (const vfs_path_t * vpath, const vfs_path_t * local, gboolean has_changed)
     /* [previous][next][first][last][top][bottom][index][help]  */
 353 {
 354     (void) vpath;
 355     (void) local;
 356     (void) has_changed;
 357 
 358     return 0;
 359 }
 360 
 361 /* --------------------------------------------------------------------------------------------- */
 362 
 363 static int
 364 local_which (struct vfs_class *me, const char *path)
     /* [previous][next][first][last][top][bottom][index][help]  */
 365 {
 366     (void) me;
 367     (void) path;
 368 
 369     return 0;                   /* Every path which other systems do not like is expected to be ours */
 370 }
 371 
 372 /* --------------------------------------------------------------------------------------------- */
 373 /*** public functions ****************************************************************************/
 374 /* --------------------------------------------------------------------------------------------- */
 375 
 376 ssize_t
 377 local_read (void *data, char *buffer, size_t count)
     /* [previous][next][first][last][top][bottom][index][help]  */
 378 {
 379     int n;
 380     int fd;
 381 
 382     if (data == NULL)
 383         return (-1);
 384 
 385     fd = *(int *) data;
 386 
 387     while ((n = read (fd, buffer, count)) == -1)
 388     {
 389 #ifdef EAGAIN
 390         if (errno == EAGAIN)
 391             continue;
 392 #endif
 393 #ifdef EINTR
 394         if (errno == EINTR)
 395             continue;
 396 #endif
 397         return (-1);
 398     }
 399 
 400     return n;
 401 }
 402 
 403 /* --------------------------------------------------------------------------------------------- */
 404 
 405 int
 406 local_close (void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 407 {
 408     int fd;
 409 
 410     if (data == NULL)
 411         return (-1);
 412 
 413     fd = *(int *) data;
 414     g_free (data);
 415     return close (fd);
 416 }
 417 
 418 /* --------------------------------------------------------------------------------------------- */
 419 
 420 int
 421 local_errno (struct vfs_class *me)
     /* [previous][next][first][last][top][bottom][index][help]  */
 422 {
 423     (void) me;
 424     return errno;
 425 }
 426 
 427 /* --------------------------------------------------------------------------------------------- */
 428 
 429 int
 430 local_fstat (void *data, struct stat *buf)
     /* [previous][next][first][last][top][bottom][index][help]  */
 431 {
 432     int fd = *(int *) data;
 433 
 434     return fstat (fd, buf);
 435 }
 436 
 437 /* --------------------------------------------------------------------------------------------- */
 438 
 439 off_t
 440 local_lseek (void *data, off_t offset, int whence)
     /* [previous][next][first][last][top][bottom][index][help]  */
 441 {
 442     int fd = *(int *) data;
 443 
 444     return lseek (fd, offset, whence);
 445 }
 446 
 447 /* --------------------------------------------------------------------------------------------- */
 448 
 449 static gboolean
 450 local_nothingisopen (vfsid id)
     /* [previous][next][first][last][top][bottom][index][help]  */
 451 {
 452     (void) id;
 453 
 454     return TRUE;
 455 }
 456 
 457 /* --------------------------------------------------------------------------------------------- */
 458 
 459 void
 460 vfs_init_localfs (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 461 {
 462     /* NULLize vfs_s_subclass members */
 463     memset (&local_subclass, 0, sizeof (local_subclass));
 464 
 465     vfs_init_class (vfs_local_ops, "localfs", VFSF_LOCAL, NULL);
 466     vfs_local_ops->which = local_which;
 467     vfs_local_ops->open = local_open;
 468     vfs_local_ops->close = local_close;
 469     vfs_local_ops->read = local_read;
 470     vfs_local_ops->write = local_write;
 471     vfs_local_ops->opendir = local_opendir;
 472     vfs_local_ops->readdir = local_readdir;
 473     vfs_local_ops->closedir = local_closedir;
 474     vfs_local_ops->stat = local_stat;
 475     vfs_local_ops->lstat = local_lstat;
 476     vfs_local_ops->fstat = local_fstat;
 477     vfs_local_ops->chmod = local_chmod;
 478     vfs_local_ops->chown = local_chown;
 479     vfs_local_ops->utime = local_utime;
 480     vfs_local_ops->readlink = local_readlink;
 481     vfs_local_ops->symlink = local_symlink;
 482     vfs_local_ops->link = local_link;
 483     vfs_local_ops->unlink = local_unlink;
 484     vfs_local_ops->rename = local_rename;
 485     vfs_local_ops->chdir = local_chdir;
 486     vfs_local_ops->ferrno = local_errno;
 487     vfs_local_ops->lseek = local_lseek;
 488     vfs_local_ops->mknod = local_mknod;
 489     vfs_local_ops->getlocalcopy = local_getlocalcopy;
 490     vfs_local_ops->ungetlocalcopy = local_ungetlocalcopy;
 491     vfs_local_ops->mkdir = local_mkdir;
 492     vfs_local_ops->rmdir = local_rmdir;
 493     vfs_local_ops->nothingisopen = local_nothingisopen;
 494     vfs_register_class (vfs_local_ops);
 495 }
 496 
 497 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */