No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / am-utils / dist / hlfsd / stubs.c
blobbaf96bc3f0ade8af2b72677492b9ff96b617a999
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 1989 Jan-Simon Pendry
6 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
7 * Copyright (c) 1989 The Regents of the University of California.
8 * All rights reserved.
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgment:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
42 * File: am-utils/hlfsd/stubs.c
44 * HLFSD was written at Columbia University Computer Science Department, by
45 * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
46 * It is being distributed under the same terms and conditions as amd does.
49 #ifdef HAVE_CONFIG_H
50 # include <config.h>
51 #endif /* HAVE_CONFIG_H */
52 #include <am_defs.h>
53 #include <hlfsd.h>
56 * STATIC VARIABLES:
58 static nfsfattr rootfattr = {NFDIR, 0040555, 2, 0, 0, 512, 512, 0,
59 1, 0, ROOTID};
60 static nfsfattr slinkfattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
61 (NFS_MAXPATHLEN + 1) / 512, 0, SLINKID};
62 /* user name file attributes */
63 static nfsfattr un_fattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
64 (NFS_MAXPATHLEN + 1) / 512, 0, INVALIDID};
65 static int started;
66 static am_nfs_fh slink;
67 static am_nfs_fh un_fhandle;
70 * GLOBALS:
72 am_nfs_fh root;
73 am_nfs_fh *root_fhp = &root;
76 /* initialize NFS file handles for hlfsd */
77 void
78 hlfsd_init_filehandles(void)
80 u_int ui;
82 ui = ROOTID;
83 memcpy(root.fh_data, &ui, sizeof(ui));
85 ui = SLINKID;
86 memcpy(slink.fh_data, &ui, sizeof(ui));
88 ui = INVALIDID;
89 memcpy(un_fhandle.fh_data, &ui, sizeof(ui));
93 voidp
94 nfsproc_null_2_svc(voidp argp, struct svc_req *rqstp)
96 static char res;
98 return (voidp) &res;
102 /* compare if two filehandles are equal */
103 static int
104 eq_fh(const am_nfs_fh *fh1, const am_nfs_fh *fh2)
106 return (!memcmp((char *) fh1, (char *) fh2, sizeof(am_nfs_fh)));
110 nfsattrstat *
111 nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
113 static nfsattrstat res;
114 uid_t uid = (uid_t) INVALIDID;
115 gid_t gid = (gid_t) INVALIDID;
117 if (!started) {
118 started++;
119 rootfattr.na_ctime = startup;
120 rootfattr.na_mtime = startup;
121 slinkfattr.na_ctime = startup;
122 slinkfattr.na_mtime = startup;
123 un_fattr.na_ctime = startup;
124 un_fattr.na_mtime = startup;
127 if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) {
128 res.ns_status = NFSERR_STALE;
129 return &res;
131 if (eq_fh(argp, &root)) {
132 #if 0
134 * XXX: increment mtime of parent directory, causes NFS clients to
135 * invalidate their cache for that directory.
136 * Some NFS clients may need this code.
138 if (uid != rootfattr.na_uid) {
139 clocktime(&rootfattr.na_mtime);
140 rootfattr.na_uid = uid;
142 #endif /* 0 */
143 res.ns_status = NFS_OK;
144 res.ns_u.ns_attr_u = rootfattr;
145 } else if (eq_fh(argp, &slink)) {
147 #ifndef MNT2_NFS_OPT_SYMTTL
149 * This code is needed to defeat Solaris 2.4's (and newer) symlink
150 * values cache. It forces the last-modified time of the symlink to be
151 * current. It is not needed if the O/S has an nfs flag to turn off the
152 * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
154 * Additionally, Linux currently ignores the nt_useconds field,
155 * so we must update the nt_seconds field every time.
157 if (uid != slinkfattr.na_uid) {
158 clocktime(&slinkfattr.na_mtime);
159 slinkfattr.na_uid = uid;
161 #endif /* not MNT2_NFS_OPT_SYMTTL */
163 res.ns_status = NFS_OK;
164 res.ns_u.ns_attr_u = slinkfattr;
165 } else {
166 if (gid != hlfs_gid) {
167 res.ns_status = NFSERR_STALE;
168 } else {
169 memset((char *) &uid, 0, sizeof(int));
170 uid = *(u_int *) argp->fh_data;
171 if (plt_search(uid) != (uid2home_t *) NULL) {
172 res.ns_status = NFS_OK;
173 un_fattr.na_fileid = uid;
174 res.ns_u.ns_attr_u = un_fattr;
175 dlog("nfs_getattr: successful search for uid=%ld, gid=%ld",
176 (long) uid, (long) gid);
177 } else { /* not found */
178 res.ns_status = NFSERR_STALE;
182 return &res;
186 nfsattrstat *
187 nfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp)
189 static nfsattrstat res = {NFSERR_ROFS};
191 return &res;
195 voidp
196 nfsproc_root_2_svc(voidp argp, struct svc_req *rqstp)
198 static char res;
200 return (voidp) &res;
204 nfsdiropres *
205 nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
207 static nfsdiropres res;
208 int idx;
209 uid_t uid = (uid_t) INVALIDID;
210 gid_t gid = (gid_t) INVALIDID;
212 if (!started) {
213 started++;
214 rootfattr.na_ctime = startup;
215 rootfattr.na_mtime = startup;
216 slinkfattr.na_ctime = startup;
217 slinkfattr.na_mtime = startup;
218 un_fattr.na_ctime = startup;
219 un_fattr.na_mtime = startup;
222 if (eq_fh(&argp->da_fhandle, &slink)) {
223 res.dr_status = NFSERR_NOTDIR;
224 return &res;
227 if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) {
228 res.dr_status = NFSERR_NOENT;
229 return &res;
231 if (eq_fh(&argp->da_fhandle, &root)) {
232 if (argp->da_name[0] == '.' &&
233 (argp->da_name[1] == '\0' ||
234 (argp->da_name[1] == '.' &&
235 argp->da_name[2] == '\0'))) {
236 #if 0
238 * XXX: increment mtime of parent directory, causes NFS clients to
239 * invalidate their cache for that directory.
240 * Some NFS clients may need this code.
242 if (uid != rootfattr.na_uid) {
243 clocktime(&rootfattr.na_mtime);
244 rootfattr.na_uid = uid;
246 #endif /* 0 */
247 res.dr_u.dr_drok_u.drok_fhandle = root;
248 res.dr_u.dr_drok_u.drok_attributes = rootfattr;
249 res.dr_status = NFS_OK;
250 return &res;
253 if (STREQ(argp->da_name, slinkname)) {
254 #ifndef MNT2_NFS_OPT_SYMTTL
256 * This code is needed to defeat Solaris 2.4's (and newer) symlink
257 * values cache. It forces the last-modified time of the symlink to be
258 * current. It is not needed if the O/S has an nfs flag to turn off the
259 * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
261 * Additionally, Linux currently ignores the nt_useconds field,
262 * so we must update the nt_seconds field every time.
264 if (uid != slinkfattr.na_uid) {
265 clocktime(&slinkfattr.na_mtime);
266 slinkfattr.na_uid = uid;
268 #endif /* not MNT2_NFS_OPT_SYMTTL */
269 res.dr_u.dr_drok_u.drok_fhandle = slink;
270 res.dr_u.dr_drok_u.drok_attributes = slinkfattr;
271 res.dr_status = NFS_OK;
272 return &res;
275 if (gid != hlfs_gid) {
276 res.dr_status = NFSERR_NOENT;
277 return &res;
280 /* if gets here, gid == hlfs_gid */
281 if ((idx = untab_index(argp->da_name)) < 0) {
282 res.dr_status = NFSERR_NOENT;
283 return &res;
284 } else { /* entry found and gid is permitted */
285 un_fattr.na_fileid = untab[idx].uid;
286 res.dr_u.dr_drok_u.drok_attributes = un_fattr;
287 memset((char *) &un_fhandle, 0, sizeof(am_nfs_fh));
288 *(u_int *) un_fhandle.fh_data = (u_int) untab[idx].uid;
289 xstrlcpy((char *) &un_fhandle.fh_data[sizeof(int)],
290 untab[idx].username,
291 sizeof(am_nfs_fh) - sizeof(int));
292 res.dr_u.dr_drok_u.drok_fhandle = un_fhandle;
293 res.dr_status = NFS_OK;
294 dlog("nfs_lookup: successful lookup for uid=%ld, gid=%ld: username=%s",
295 (long) uid, (long) gid, untab[idx].username);
296 return &res;
298 } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */
300 res.dr_status = NFSERR_STALE;
301 return &res;
305 nfsreadlinkres *
306 nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
308 static nfsreadlinkres res;
309 uid_t userid = (uid_t) INVALIDID;
310 gid_t groupid = hlfs_gid + 1; /* anything not hlfs_gid */
311 int retval = 0;
312 char *path_val = (char *) NULL;
313 char *username;
314 static uid_t last_uid = (uid_t) INVALIDID;
316 if (eq_fh(argp, &root)) {
317 res.rlr_status = NFSERR_ISDIR;
318 } else if (eq_fh(argp, &slink)) {
319 if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0)
320 return (nfsreadlinkres *) NULL;
322 clocktime(&slinkfattr.na_atime);
324 res.rlr_status = NFS_OK;
325 if (groupid == hlfs_gid) {
326 res.rlr_u.rlr_data_u = DOTSTRING;
327 } else if (!(res.rlr_u.rlr_data_u = path_val = homedir(userid, groupid))) {
329 * parent process (fork in homedir()) continues
330 * processing, by getting a NULL returned as a
331 * "special". Child returns result.
333 return (nfsreadlinkres *) NULL;
336 } else { /* check if asked for user mailbox */
338 if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) {
339 return (nfsreadlinkres *) NULL;
342 if (groupid == hlfs_gid) {
343 memset((char *) &userid, 0, sizeof(int));
344 userid = *(u_int *) argp->fh_data;
345 username = (char *) &argp->fh_data[sizeof(int)];
346 if (!(res.rlr_u.rlr_data_u = mailbox(userid, username)))
347 return (nfsreadlinkres *) NULL;
348 } else {
349 res.rlr_status = NFSERR_STALE;
353 /* print info, but try to avoid repetitions */
354 if (userid != last_uid) {
355 plog(XLOG_USER, "mailbox for uid=%ld, gid=%ld is %s",
356 (long) userid, (long) groupid, (char *) res.rlr_u.rlr_data_u);
357 last_uid = userid;
360 /* I don't think it will pass this if -D fork */
361 if (serverpid == getpid())
362 return &res;
364 if (!svc_sendreply(nfsxprt, (XDRPROC_T_TYPE) xdr_readlinkres, (SVC_IN_ARG_TYPE) &res))
365 svcerr_systemerr(nfsxprt);
368 * Child exists here. We need to determine which
369 * exist status to return. The exit status
370 * is gathered using wait() and determines
371 * if we returned $HOME/.hlfsspool or $ALTDIR. The parent
372 * needs this info so it can update the lookup table.
374 if (path_val && alt_spooldir && STREQ(path_val, alt_spooldir))
375 retval = 1; /* could not get real home dir (or uid 0 user) */
376 else
377 retval = 0;
380 * If asked for -D nofork, then must return the value,
381 * NOT exit, or else the main hlfsd server exits.
382 * If -D fork (default), then we do want to exit from the process.
383 * Bug: where is that status information being collected?
385 if (amuDebug(D_FORK))
386 exit(retval);
387 else
388 return &res;
392 nfsreadres *
393 nfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp)
395 static nfsreadres res = {NFSERR_ACCES};
397 return &res;
401 voidp
402 nfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp)
404 static char res;
406 return (voidp) &res;
410 nfsattrstat *
411 nfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp)
413 static nfsattrstat res = {NFSERR_ROFS};
415 return &res;
419 nfsdiropres *
420 nfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
422 static nfsdiropres res = {NFSERR_ROFS};
424 return &res;
428 nfsstat *
429 nfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
431 static nfsstat res = {NFSERR_ROFS};
433 return &res;
437 nfsstat *
438 nfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp)
440 static nfsstat res = {NFSERR_ROFS};
442 return &res;
446 nfsstat *
447 nfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp)
449 static nfsstat res = {NFSERR_ROFS};
451 return &res;
455 nfsstat *
456 nfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp)
458 static nfsstat res = {NFSERR_ROFS};
460 return &res;
464 nfsdiropres *
465 nfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
467 static nfsdiropres res = {NFSERR_ROFS};
469 return &res;
473 nfsstat *
474 nfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
476 static nfsstat res = {NFSERR_ROFS};
478 return &res;
482 nfsreaddirres *
483 nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
485 static nfsreaddirres res;
486 static nfsentry slinkent = {SLINKID, NULL, {SLINKCOOKIE}};
487 static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent};
488 static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent};
490 slinkent.ne_name = slinkname;
492 if (eq_fh(&argp->rda_fhandle, &slink)) {
493 res.rdr_status = NFSERR_NOTDIR;
494 } else if (eq_fh(&argp->rda_fhandle, &root)) {
495 clocktime(&rootfattr.na_atime);
497 res.rdr_status = NFS_OK;
498 switch (argp->rda_cookie[0]) {
499 case 0:
500 res.rdr_u.rdr_reply_u.dl_entries = &dotent;
501 break;
502 case DOTCOOKIE:
503 res.rdr_u.rdr_reply_u.dl_entries = &dotdotent;
504 break;
505 case DOTDOTCOOKIE:
506 res.rdr_u.rdr_reply_u.dl_entries = &slinkent;
507 break;
508 case SLINKCOOKIE:
509 res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) NULL;
510 break;
512 res.rdr_u.rdr_reply_u.dl_eof = TRUE;
513 } else {
514 res.rdr_status = NFSERR_STALE;
516 return &res;
520 nfsstatfsres *
521 nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
523 static nfsstatfsres res = {NFS_OK};
525 res.sfr_u.sfr_reply_u.sfrok_tsize = 1024;
526 res.sfr_u.sfr_reply_u.sfrok_bsize = 1024;
529 * Some "df" programs automatically assume that file systems
530 * with zero blocks are meta-filesystems served by automounters.
532 res.sfr_u.sfr_reply_u.sfrok_blocks = 0;
533 res.sfr_u.sfr_reply_u.sfrok_bfree = 0;
534 res.sfr_u.sfr_reply_u.sfrok_bavail = 0;
536 return &res;