File: nfsexport.c

package info (click to toggle)
nfs-utils 1%3A1.3.4-2.1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 6,000 kB
  • sloc: ansic: 36,344; sh: 4,948; python: 1,342; makefile: 764
file content (134 lines) | stat: -rw-r--r-- 3,195 bytes parent folder | download | duplicates (3)
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
/*
 * support/nfs/export.c
 *
 * Add or delete an NFS export in knfsd.
 *
 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <sys/types.h>
#include <asm/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#include "nfslib.h"
#include "misc.h"
#include "xcommon.h"

	/* if /proc/net/rpc/... exists, then 
	 * write to it, as that interface is more stable.
	 * Write:
	 *  client fsidtype fsid path
	 * to /proc/net/rpc/nfsd.fh/channel
	 * and
	 *  client path expiry flags anonuid anongid fsid
	 * to /proc/net/rpc/nfsd.export/channel
	 */

static int
exp_unexp(struct nfsctl_export *exp, int export)
{
	char buf[RPC_CHAN_BUF_SIZE], *bp;
	struct stat stb;
	__u32 fsid;
	char fsidstr[8];
	__u16 dev;
	__u32 inode;
	int err = 0, f, blen;

	f = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
	if (f < 0) return -1;

	bp = buf; blen = sizeof(buf);
	qword_add(&bp, &blen, exp->ex_client);
	qword_add(&bp, &blen, exp->ex_path);
	if (export) {
		qword_addint(&bp, &blen, 0x7fffffff);
		qword_addint(&bp, &blen, exp->ex_flags);
		qword_addint(&bp, &blen, exp->ex_anon_uid);
		qword_addint(&bp, &blen, exp->ex_anon_gid);
		qword_addint(&bp, &blen, exp->ex_dev);
	} else
		qword_addint(&bp, &blen, 1);
	qword_addeol(&bp, &blen);
	if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
		err = -1;
	close(f);

	if (stat(exp->ex_path, &stb) != 0)
		return -1;

	f = open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY);
	if (f < 0) return -1;
	if (exp->ex_flags & NFSEXP_FSID) {
		bp = buf; blen = sizeof(buf);
		qword_add(&bp, &blen, exp->ex_client);
		qword_addint(&bp, &blen, 1);
		fsid = exp->ex_dev;
		qword_addhex(&bp, &blen, (char*)&fsid, 4);
		if (export) {
			qword_addint(&bp, &blen, 0x7fffffff);
			qword_add(&bp, &blen, exp->ex_path);
		} else
			qword_addint(&bp, &blen, 1);
		qword_addeol(&bp, &blen);
		if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
			err = -1;
	}

	bp = buf; blen = sizeof(buf);
	qword_add(&bp, &blen, exp->ex_client);
	qword_addint(&bp, &blen, 0);
	dev = htons(major(stb.st_dev)); memcpy(fsidstr, &dev, 2);
	dev = htons(minor(stb.st_dev)); memcpy(fsidstr+2, &dev, 2);
	inode = stb.st_ino; memcpy(fsidstr+4, &inode, 4);
	
	qword_addhex(&bp, &blen, fsidstr, 8);
	if (export) {
		qword_addint(&bp, &blen, 0x7fffffff);
		qword_add(&bp, &blen, exp->ex_path);
	} else
		qword_addint(&bp, &blen, 1);
	qword_addeol(&bp, &blen);
	if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
		err = -1;
	close(f);

	return err;
}

int
nfsexport(struct nfsctl_export *exp)
{
	struct nfsctl_arg	arg;
	int fd;
	if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY))>= 0) {
		close(fd);
		return exp_unexp(exp, 1);
	}
	arg.ca_version = NFSCTL_VERSION;
	memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
	return nfsctl(NFSCTL_EXPORT, &arg, NULL);
}

int
nfsunexport(struct nfsctl_export *exp)
{
	struct nfsctl_arg	arg;

	int fd;
	if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY))>= 0) {
		close(fd);
		return exp_unexp(exp, 0);
	}

	arg.ca_version = NFSCTL_VERSION;
	memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
	return nfsctl(NFSCTL_UNEXPORT, &arg, NULL);
}