File: getattr.c

package info (click to toggle)
netstd 3.07-2hamm.5
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 6,384 kB
  • ctags: 9,087
  • sloc: ansic: 72,547; cpp: 6,141; makefile: 1,681; yacc: 1,615; sh: 1,220; perl: 303; awk: 46
file content (146 lines) | stat: -rw-r--r-- 3,552 bytes parent folder | download | duplicates (2)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * 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>
 *
 *		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"

/*
 * The NFS version 2 specification fails to mention all of
 * these file types, but they exist in the nfs_prot.x file.
 */
#define ftype_map(st_mode) (_ftype_map[((st_mode) & S_IFMT) >> 12])

ftype _ftype_map[16] =
{
#ifdef S_IFIFO
	NFNON, NFFIFO, NFCHR, NFBAD,
#else
	NFNON, NFBAD, NFCHR, NFBAD,
#endif
	NFDIR, NFBAD, NFBLK, NFBAD,
	NFREG, NFBAD, NFLNK, NFBAD,
	NFSOCK, NFBAD, NFBAD, NFBAD,
};

/*
 * Get file attributes based on file handle
 */
nfsstat fh_getattr(fh, attr, stat_optimize, rqstp)
nfs_fh		*fh;
fattr		*attr;
struct stat	*stat_optimize;
struct svc_req	*rqstp;
{
	fhcache *fhc;

	if ((fhc = fh_find((svc_fh*)fh, FHFIND_FEXISTS)) == NULL) {
		Dprintf(D_CALL, "getattr: failed! No such file.\n");
		return (NFSERR_STALE);
	}
	return fhc_getattr(fhc, attr, stat_optimize, rqstp);
}

/*
 * Get file attributes given the path.
 */
nfsstat fhc_getattr(fhc, attr, stat_optimize, rqstp)
fhcache		*fhc;
fattr		*attr;
struct stat	*stat_optimize;
struct svc_req	*rqstp;
{
#ifdef DEBUG
	char buff[1024];
	char *sp;
#endif
	/* nfsstat status; */
	struct stat *s;
	struct stat sbuf;

	if (stat_optimize != NULL
	 && stat_optimize->st_nlink != 0)
		s = stat_optimize;
	else if (lstat(fhc->path, (s = &sbuf)) != 0) {
		Dprintf(D_CALL, "getattr(%s): failed!  errno=%d\n", 
			fhc->path, errno);
		return nfs_errno();
	}
	attr->type = ftype_map(s->st_mode);
	attr->mode = s->st_mode;
	attr->nlink = s->st_nlink;
	attr->uid = ruid(s->st_uid, nfsmount, rqstp);
	attr->gid = rgid(s->st_gid, nfsmount, rqstp);

	/* Some applications need the exact symlink size */
#if defined(S_ISLNK)
	if (S_ISLNK(s->st_mode))
		attr->size = MIN(s->st_size, NFS_MAXPATHLEN);
	else
#endif
		attr->size = s->st_size;
#ifdef HAVE_ST_BLKSIZE
	attr->blocksize = s->st_blksize;
#else /* !HAVE_ST_BLKSIZE */
#ifdef BUFSIZ
	attr->blocksize = BUFSIZ;
#else /* BUFSIZ */
	attr->blocksize = 1024;
#endif /* !BUFSIZ */
#endif /* !HAVE_ST_BLKSIZE */
	attr->rdev = s->st_rdev;
#ifdef HAVE_ST_BLOCKS
	attr->blocks = s->st_blocks;
#else
	attr->blocks = st_blocks(s);
#endif
#if 0
	if (nfsmount->o.cross_mounts) {
		attr->fsid = 1;
		attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
	} else {
		attr->fsid = s->st_dev;
		attr->fileid = covered_ino(fhc->path);
	}
#else
	attr->fsid   = 1;
	attr->fileid = fh_psi((nfs_fh *)&(fhc->h));
#endif
	attr->atime.seconds = s->st_atime;
	attr->atime.useconds = 0;
	attr->mtime.seconds = s->st_mtime;
	attr->mtime.useconds = 0;
	attr->ctime.seconds = s->st_ctime;
	attr->ctime.useconds = 0;

#ifdef DEBUG
	sp = buff;
	sprintf(sp, " t=%d, m=%o, lk=%d, u/g=%d/%d, sz=%d, bsz=%d",
		attr->type, attr->mode, attr->nlink,
		attr->uid, attr->gid, attr->size,
		attr->blocksize);
	sp += strlen(sp);
	if (attr->type == NFCHR || attr->type == NFBLK) {
		sprintf(sp, " rdev=%d/%d", (attr->rdev >> 8) & 0xff, attr->rdev & 0xff);
		sp += strlen(sp);
		sprintf(sp, "\n  blks=%d, fsid=%d, psi=%d, at=%d, mt=%d, ct=%d\n",
			attr->blocks, attr->fsid, attr->fileid,
			attr->atime.seconds,
			attr->mtime.seconds,
			attr->ctime.seconds);
		sp += strlen(sp);
	}
	Dprintf(D_CALL, "%s", buff);
#endif

	return (NFS_OK);
}