1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/*
* getattr This module handles the NFS attributes.
*
* Authors: Mark A. Shand, May 1988
* Donald J. Becker, <becker@super.org>
* Rick Sladkey, <jrs@world.std.com>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Olaf Kirch, <okir@monad.swb.de>
*
* Copyright 1988 Mark A. Shand
* This software maybe be used for any purpose provided
* the above copyright notice is retained. It is supplied
* as is, with no warranty expressed or implied.
*/
#include "nfsd.h"
/*
* Set file attributes based on file handle
*/
nfsstat fh_setattr(fh, attr, s, rqstp, flags)
nfs_fh *fh;
sattr *attr;
struct stat *s;
struct svc_req *rqstp;
int flags;
{
char *path;
nfsstat status;
if ((path = fh_path(fh, &status)) == NULL) {
Dprintf(D_CALL, "setattr failed: No such file.\n");
return (NFSERR_STALE);
}
return setattr(path, attr, s, rqstp, flags);
}
/*
* Set file attributes given the path. The flags argument
* determines if we have to stat the file or if the stat buf
* passed in s contains valid data.
* As we go along and modify the file attributes, we update the
* fields of this stat structure.
*/
nfsstat setattr(path, attr, s, rqstp, flags)
char *path;
sattr *attr;
struct stat *s;
struct svc_req *rqstp;
int flags;
{
struct stat sbuf;
if (s == NULL) {
s = &sbuf;
flags |= SATTR_STAT;
}
if ((flags & SATTR_STAT) && lstat(path, (s = &sbuf)) < 0) {
Dprintf(D_CALL, "setattr: couldn't stat %s! errno=%d\n",
path, errno);
return nfs_errno();
}
if (flags & SATTR_SIZE) {
unsigned int size = attr->size;
if (S_ISREG(s->st_mode) && size != -1) {
if (truncate(path, size) < 0)
goto failure;
s->st_size = size;
}
}
if (flags & SATTR_UTIMES) {
unsigned int a_secs = attr->atime.seconds;
unsigned int m_secs = attr->mtime.seconds;
if ((a_secs != -1 && a_secs != s->st_atime)
|| (m_secs != -1 && m_secs != s->st_mtime)) {
struct timeval tvp[2];
tvp[0].tv_sec = attr->atime.seconds;
tvp[0].tv_usec = attr->atime.useconds;
tvp[1].tv_sec = attr->mtime.seconds;
tvp[1].tv_usec = attr->mtime.useconds;
if (utimes(path, tvp) < 0)
goto failure;
if (attr->mtime.seconds != -1)
s->st_atime = attr->atime.seconds;
if (attr->mtime.seconds != -1)
s->st_mtime = attr->mtime.seconds;
}
}
if (flags & SATTR_CHMOD) {
unsigned int mode = attr->mode;
if (mode != -1 && mode != 0xFFFF /* ultrix bug */
&& (mode & 07777) != (s->st_mode & 07777)) {
if (chmod(path, mode) < 0)
goto failure;
s->st_mode = (s->st_mode & ~07777) | (mode & 07777);
}
}
if (flags & SATTR_CHOWN) {
uid_t uid = attr->uid;
gid_t gid = attr->gid;
if (uid != (uid_t)-1)
uid = luid(uid, nfsmount, rqstp);
if (gid != (gid_t)-1)
gid = lgid(gid, nfsmount, rqstp);
if ((uid != (uid_t)-1 && uid != s->st_uid)
|| (gid != (gid_t)-1 && gid != s->st_gid)) {
if (lchown(path, uid, gid) < 0)
goto failure;
if (uid != (uid_t)-1) s->st_uid = uid;
if (gid != (gid_t)-1) s->st_gid = gid;
}
}
return (NFS_OK);
failure:
return nfs_errno();
}
|