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_fgetflags
  10. local_fsetflags
  11. local_utime
  12. local_readlink
  13. local_unlink
  14. local_symlink
  15. local_write
  16. local_rename
  17. local_chdir
  18. local_mknod
  19. local_link
  20. local_mkdir
  21. local_rmdir
  22. local_getlocalcopy
  23. local_ungetlocalcopy
  24. local_which
  25. local_read
  26. local_close
  27. local_errno
  28. local_fstat
  29. local_lseek
  30. local_nothingisopen
  31. vfs_init_localfs

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

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