linux-bk/fs/hostfs/hostfs_user.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
   3 * Licensed under the GPL
   4 */
   5
   6#include <unistd.h>
   7#include <stdio.h>
   8#include <fcntl.h>
   9#include <dirent.h>
  10#include <errno.h>
  11#include <utime.h>
  12#include <string.h>
  13#include <sys/stat.h>
  14#include <sys/time.h>
  15#include <sys/vfs.h>
  16#include "hostfs.h"
  17#include "kern_util.h"
  18#include "user.h"
  19
  20int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
  21              int *nlink_out, int *uid_out, int *gid_out,
  22              unsigned long long *size_out, struct timespec *atime_out,
  23              struct timespec *mtime_out, struct timespec *ctime_out,
  24              int *blksize_out, unsigned long long *blocks_out)
  25{
  26        struct stat64 buf;
  27
  28        if(lstat64(path, &buf) < 0)
  29                return(-errno);
  30
  31        /* See the Makefile for why STAT64_INO_FIELD is passed in
  32         * by the build
  33         */
  34        if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
  35        if(mode_out != NULL) *mode_out = buf.st_mode;
  36        if(nlink_out != NULL) *nlink_out = buf.st_nlink;
  37        if(uid_out != NULL) *uid_out = buf.st_uid;
  38        if(gid_out != NULL) *gid_out = buf.st_gid;
  39        if(size_out != NULL) *size_out = buf.st_size;
  40        if(atime_out != NULL) {
  41                atime_out->tv_sec = buf.st_atime;
  42                atime_out->tv_nsec = 0;
  43        }
  44        if(mtime_out != NULL) {
  45                mtime_out->tv_sec = buf.st_mtime;
  46                mtime_out->tv_nsec = 0;
  47        }
  48        if(ctime_out != NULL) {
  49                ctime_out->tv_sec = buf.st_ctime;
  50                ctime_out->tv_nsec = 0;
  51        }
  52        if(blksize_out != NULL) *blksize_out = buf.st_blksize;
  53        if(blocks_out != NULL) *blocks_out = buf.st_blocks;
  54        return(0);
  55}
  56
  57int file_type(const char *path, int *maj, int *min)
  58{
  59        struct stat64 buf;
  60
  61        if(lstat64(path, &buf) < 0)
  62                return(-errno);
  63        /*We cannot pass rdev as is because glibc and the kernel disagree
  64         *about its definition.*/
  65        if(maj != NULL)
  66                *maj = major(buf.st_rdev);
  67        if(min != NULL)
  68                *min = minor(buf.st_rdev);
  69
  70        if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
  71        else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
  72        else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
  73        else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
  74        else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
  75        else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
  76        else return(OS_TYPE_FILE);
  77}
  78
  79int access_file(char *path, int r, int w, int x)
  80{
  81        int mode = 0;
  82
  83        if(r) mode = R_OK;
  84        if(w) mode |= W_OK;
  85        if(x) mode |= X_OK;
  86        if(access(path, mode) != 0) return(-errno);
  87        else return(0);
  88}
  89
  90int open_file(char *path, int r, int w, int append)
  91{
  92        int mode = 0, fd;
  93
  94        if(r && !w)
  95                mode = O_RDONLY;
  96        else if(!r && w)
  97                mode = O_WRONLY;
  98        else if(r && w)
  99                mode = O_RDWR;
 100        else panic("Impossible mode in open_file");
 101
 102        if(append)
 103                mode |= O_APPEND;
 104        fd = open64(path, mode);
 105        if(fd < 0) return(-errno);
 106        else return(fd);
 107}
 108
 109void *open_dir(char *path, int *err_out)
 110{
 111        DIR *dir;
 112
 113        dir = opendir(path);
 114        *err_out = errno;
 115        if(dir == NULL) return(NULL);
 116        return(dir);
 117}
 118
 119char *read_dir(void *stream, unsigned long long *pos,
 120               unsigned long long *ino_out, int *len_out)
 121{
 122        DIR *dir = stream;
 123        struct dirent *ent;
 124
 125        seekdir(dir, *pos);
 126        ent = readdir(dir);
 127        if(ent == NULL) return(NULL);
 128        *len_out = strlen(ent->d_name);
 129        *ino_out = ent->d_ino;
 130        *pos = telldir(dir);
 131        return(ent->d_name);
 132}
 133
 134int read_file(int fd, unsigned long long *offset, char *buf, int len)
 135{
 136        int n;
 137
 138        n = pread64(fd, buf, len, *offset);
 139        if(n < 0) return(-errno);
 140        *offset += n;
 141        return(n);
 142}
 143
 144int write_file(int fd, unsigned long long *offset, const char *buf, int len)
 145{
 146        int n;
 147
 148        n = pwrite64(fd, buf, len, *offset);
 149        if(n < 0) return(-errno);
 150        *offset += n;
 151        return(n);
 152}
 153
 154int lseek_file(int fd, long long offset, int whence)
 155{
 156        int ret;
 157
 158        ret = lseek64(fd, offset, whence);
 159        if(ret < 0) return(-errno);
 160        return(0);
 161}
 162
 163void close_file(void *stream)
 164{
 165        close(*((int *) stream));
 166}
 167
 168void close_dir(void *stream)
 169{
 170        closedir(stream);
 171}
 172
 173int file_create(char *name, int ur, int uw, int ux, int gr,
 174                int gw, int gx, int or, int ow, int ox)
 175{
 176        int mode, fd;
 177
 178        mode = 0;
 179        mode |= ur ? S_IRUSR : 0;
 180        mode |= uw ? S_IWUSR : 0;
 181        mode |= ux ? S_IXUSR : 0;
 182        mode |= gr ? S_IRGRP : 0;
 183        mode |= gw ? S_IWGRP : 0;
 184        mode |= gx ? S_IXGRP : 0;
 185        mode |= or ? S_IROTH : 0;
 186        mode |= ow ? S_IWOTH : 0;
 187        mode |= ox ? S_IXOTH : 0;
 188        fd = open64(name, O_CREAT | O_RDWR, mode);
 189        if(fd < 0)
 190                return(-errno);
 191        return(fd);
 192}
 193
 194int set_attr(const char *file, struct hostfs_iattr *attrs)
 195{
 196        struct utimbuf buf;
 197        int err, ma;
 198
 199        if(attrs->ia_valid & HOSTFS_ATTR_MODE){
 200                if(chmod(file, attrs->ia_mode) != 0) return(-errno);
 201        }
 202        if(attrs->ia_valid & HOSTFS_ATTR_UID){
 203                if(chown(file, attrs->ia_uid, -1)) return(-errno);
 204        }
 205        if(attrs->ia_valid & HOSTFS_ATTR_GID){
 206                if(chown(file, -1, attrs->ia_gid)) return(-errno);
 207        }
 208        if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
 209                if(truncate(file, attrs->ia_size)) return(-errno);
 210        }
 211        ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
 212        if((attrs->ia_valid & ma) == ma){
 213                buf.actime = attrs->ia_atime.tv_sec;
 214                buf.modtime = attrs->ia_mtime.tv_sec;
 215                if(utime(file, &buf) != 0) return(-errno);
 216        }
 217        else {
 218                struct timespec ts;
 219
 220                if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
 221                        err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
 222                                        NULL, NULL, &ts, NULL, NULL, NULL);
 223                        if(err != 0)
 224                                return(err);
 225                        buf.actime = attrs->ia_atime.tv_sec;
 226                        buf.modtime = ts.tv_sec;
 227                        if(utime(file, &buf) != 0)
 228                                return(-errno);
 229                }
 230                if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
 231                        err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
 232                                        NULL, &ts, NULL, NULL, NULL, NULL);
 233                        if(err != 0)
 234                                return(err);
 235                        buf.actime = ts.tv_sec;
 236                        buf.modtime = attrs->ia_mtime.tv_sec;
 237                        if(utime(file, &buf) != 0)
 238                                return(-errno);
 239                }
 240        }
 241        if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
 242        if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
 243                err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
 244                                &attrs->ia_atime, &attrs->ia_mtime, NULL,
 245                                NULL, NULL);
 246                if(err != 0) return(err);
 247        }
 248        return(0);
 249}
 250
 251int make_symlink(const char *from, const char *to)
 252{
 253        int err;
 254
 255        err = symlink(to, from);
 256        if(err) return(-errno);
 257        return(0);
 258}
 259
 260int unlink_file(const char *file)
 261{
 262        int err;
 263
 264        err = unlink(file);
 265        if(err) return(-errno);
 266        return(0);
 267}
 268
 269int do_mkdir(const char *file, int mode)
 270{
 271        int err;
 272
 273        err = mkdir(file, mode);
 274        if(err) return(-errno);
 275        return(0);
 276}
 277
 278int do_rmdir(const char *file)
 279{
 280        int err;
 281
 282        err = rmdir(file);
 283        if(err) return(-errno);
 284        return(0);
 285}
 286
 287int do_mknod(const char *file, int mode, int dev)
 288{
 289        int err;
 290
 291        err = mknod(file, mode, dev);
 292        if(err) return(-errno);
 293        return(0);
 294}
 295
 296int link_file(const char *to, const char *from)
 297{
 298        int err;
 299
 300        err = link(to, from);
 301        if(err) return(-errno);
 302        return(0);
 303}
 304
 305int do_readlink(char *file, char *buf, int size)
 306{
 307        int n;
 308
 309        n = readlink(file, buf, size);
 310        if(n < 0)
 311                return(-errno);
 312        if(n < size)
 313                buf[n] = '\0';
 314        return(n);
 315}
 316
 317int rename_file(char *from, char *to)
 318{
 319        int err;
 320
 321        err = rename(from, to);
 322        if(err < 0) return(-errno);
 323        return(0);
 324}
 325
 326int do_statfs(char *root, long *bsize_out, long long *blocks_out,
 327              long long *bfree_out, long long *bavail_out,
 328              long long *files_out, long long *ffree_out,
 329              void *fsid_out, int fsid_size, long *namelen_out,
 330              long *spare_out)
 331{
 332        struct statfs64 buf;
 333        int err;
 334
 335        err = statfs64(root, &buf);
 336        if(err < 0) return(-errno);
 337        *bsize_out = buf.f_bsize;
 338        *blocks_out = buf.f_blocks;
 339        *bfree_out = buf.f_bfree;
 340        *bavail_out = buf.f_bavail;
 341        *files_out = buf.f_files;
 342        *ffree_out = buf.f_ffree;
 343        memcpy(fsid_out, &buf.f_fsid,
 344               sizeof(buf.f_fsid) > fsid_size ? fsid_size :
 345               sizeof(buf.f_fsid));
 346        *namelen_out = buf.f_namelen;
 347        spare_out[0] = buf.f_spare[0];
 348        spare_out[1] = buf.f_spare[1];
 349        spare_out[2] = buf.f_spare[2];
 350        spare_out[3] = buf.f_spare[3];
 351        spare_out[4] = buf.f_spare[4];
 352        spare_out[5] = buf.f_spare[5];
 353        return(0);
 354}
 355
 356/*
 357 * Overrides for Emacs so that we follow Linus's tabbing style.
 358 * Emacs will notice this stuff at the end of the file and automatically
 359 * adjust the settings for this buffer only.  This must remain at the end
 360 * of the file.
 361 * ---------------------------------------------------------------------------
 362 * Local variables:
 363 * c-file-style: "linux"
 364 * End:
 365 */
 366
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.