turns printfs back on
[freebsd-src/fkvm-freebsd.git] / contrib / amd / hlfsd / stubs.c
blobbecf402c1ecbe82bff463ef1f9c37bd6e8bf43fd
1 /*
2 * Copyright (c) 1997-2006 Erez Zadok
3 * Copyright (c) 1989 Jan-Simon Pendry
4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgment:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
40 * File: am-utils/hlfsd/stubs.c
42 * HLFSD was written at Columbia University Computer Science Department, by
43 * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu>
44 * It is being distributed under the same terms and conditions as amd does.
47 #ifdef HAVE_CONFIG_H
48 # include <config.h>
49 #endif /* HAVE_CONFIG_H */
50 #include <am_defs.h>
51 #include <hlfsd.h>
54 * STATIC VARIABLES:
56 static nfsfattr rootfattr = {NFDIR, 0040555, 2, 0, 0, 512, 512, 0,
57 1, 0, ROOTID};
58 static nfsfattr slinkfattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
59 (NFS_MAXPATHLEN + 1) / 512, 0, SLINKID};
60 /* user name file attributes */
61 static nfsfattr un_fattr = {NFLNK, 0120777, 1, 0, 0, NFS_MAXPATHLEN, 512, 0,
62 (NFS_MAXPATHLEN + 1) / 512, 0, INVALIDID};
63 static int started;
64 static am_nfs_fh slink;
65 static am_nfs_fh un_fhandle;
68 * GLOBALS:
70 am_nfs_fh root;
71 am_nfs_fh *root_fhp = &root;
74 /* initialize NFS file handles for hlfsd */
75 void
76 hlfsd_init_filehandles(void)
78 u_int ui;
80 ui = ROOTID;
81 memcpy(root.fh_data, &ui, sizeof(ui));
83 ui = SLINKID;
84 memcpy(slink.fh_data, &ui, sizeof(ui));
86 ui = INVALIDID;
87 memcpy(un_fhandle.fh_data, &ui, sizeof(ui));
91 voidp
92 nfsproc_null_2_svc(voidp argp, struct svc_req *rqstp)
94 static char res;
96 return (voidp) &res;
100 /* compare if two filehandles are equal */
101 static int
102 eq_fh(const am_nfs_fh *fh1, const am_nfs_fh *fh2)
104 return (!memcmp((char *) fh1, (char *) fh2, sizeof(am_nfs_fh)));
108 nfsattrstat *
109 nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
111 static nfsattrstat res;
112 uid_t uid = (uid_t) INVALIDID;
113 gid_t gid = (gid_t) INVALIDID;
115 if (!started) {
116 started++;
117 rootfattr.na_ctime = startup;
118 rootfattr.na_mtime = startup;
119 slinkfattr.na_ctime = startup;
120 slinkfattr.na_mtime = startup;
121 un_fattr.na_ctime = startup;
122 un_fattr.na_mtime = startup;
125 if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) {
126 res.ns_status = NFSERR_STALE;
127 return &res;
129 if (eq_fh(argp, &root)) {
130 #if 0
132 * XXX: increment mtime of parent directory, causes NFS clients to
133 * invalidate their cache for that directory.
134 * Some NFS clients may need this code.
136 if (uid != rootfattr.na_uid) {
137 clocktime(&rootfattr.na_mtime);
138 rootfattr.na_uid = uid;
140 #endif
141 res.ns_status = NFS_OK;
142 res.ns_u.ns_attr_u = rootfattr;
143 } else if (eq_fh(argp, &slink)) {
145 #ifndef MNT2_NFS_OPT_SYMTTL
147 * This code is needed to defeat Solaris 2.4's (and newer) symlink
148 * values cache. It forces the last-modified time of the symlink to be
149 * current. It is not needed if the O/S has an nfs flag to turn off the
150 * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
152 * Additionally, Linux currently ignores the nt_useconds field,
153 * so we must update the nt_seconds field every time.
155 if (uid != slinkfattr.na_uid) {
156 clocktime(&slinkfattr.na_mtime);
157 slinkfattr.na_uid = uid;
159 #endif /* not MNT2_NFS_OPT_SYMTTL */
161 res.ns_status = NFS_OK;
162 res.ns_u.ns_attr_u = slinkfattr;
163 } else {
164 if (gid != hlfs_gid) {
165 res.ns_status = NFSERR_STALE;
166 } else {
167 memset((char *) &uid, 0, sizeof(int));
168 uid = *(u_int *) argp->fh_data;
169 if (plt_search(uid) != (uid2home_t *) NULL) {
170 res.ns_status = NFS_OK;
171 un_fattr.na_fileid = uid;
172 res.ns_u.ns_attr_u = un_fattr;
173 dlog("nfs_getattr: successful search for uid=%ld, gid=%ld",
174 (long) uid, (long) gid);
175 } else { /* not found */
176 res.ns_status = NFSERR_STALE;
180 return &res;
184 nfsattrstat *
185 nfsproc_setattr_2_svc(nfssattrargs *argp, struct svc_req *rqstp)
187 static nfsattrstat res = {NFSERR_ROFS};
189 return &res;
193 voidp
194 nfsproc_root_2_svc(voidp argp, struct svc_req *rqstp)
196 static char res;
198 return (voidp) &res;
202 nfsdiropres *
203 nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
205 static nfsdiropres res;
206 int idx;
207 uid_t uid = (uid_t) INVALIDID;
208 gid_t gid = (gid_t) INVALIDID;
210 if (!started) {
211 started++;
212 rootfattr.na_ctime = startup;
213 rootfattr.na_mtime = startup;
214 slinkfattr.na_ctime = startup;
215 slinkfattr.na_mtime = startup;
216 un_fattr.na_ctime = startup;
217 un_fattr.na_mtime = startup;
220 if (eq_fh(&argp->da_fhandle, &slink)) {
221 res.dr_status = NFSERR_NOTDIR;
222 return &res;
225 if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) {
226 res.dr_status = NFSERR_NOENT;
227 return &res;
229 if (eq_fh(&argp->da_fhandle, &root)) {
230 if (argp->da_name[0] == '.' &&
231 (argp->da_name[1] == '\0' ||
232 (argp->da_name[1] == '.' &&
233 argp->da_name[2] == '\0'))) {
234 #if 0
236 * XXX: increment mtime of parent directory, causes NFS clients to
237 * invalidate their cache for that directory.
238 * Some NFS clients may need this code.
240 if (uid != rootfattr.na_uid) {
241 clocktime(&rootfattr.na_mtime);
242 rootfattr.na_uid = uid;
244 #endif
245 res.dr_u.dr_drok_u.drok_fhandle = root;
246 res.dr_u.dr_drok_u.drok_attributes = rootfattr;
247 res.dr_status = NFS_OK;
248 return &res;
251 if (STREQ(argp->da_name, slinkname)) {
252 #ifndef MNT2_NFS_OPT_SYMTTL
254 * This code is needed to defeat Solaris 2.4's (and newer) symlink
255 * values cache. It forces the last-modified time of the symlink to be
256 * current. It is not needed if the O/S has an nfs flag to turn off the
257 * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
259 * Additionally, Linux currently ignores the nt_useconds field,
260 * so we must update the nt_seconds field every time.
262 if (uid != slinkfattr.na_uid) {
263 clocktime(&slinkfattr.na_mtime);
264 slinkfattr.na_uid = uid;
266 #endif /* not MNT2_NFS_OPT_SYMTTL */
267 res.dr_u.dr_drok_u.drok_fhandle = slink;
268 res.dr_u.dr_drok_u.drok_attributes = slinkfattr;
269 res.dr_status = NFS_OK;
270 return &res;
273 if (gid != hlfs_gid) {
274 res.dr_status = NFSERR_NOENT;
275 return &res;
278 /* if gets here, gid == hlfs_gid */
279 if ((idx = untab_index(argp->da_name)) < 0) {
280 res.dr_status = NFSERR_NOENT;
281 return &res;
282 } else { /* entry found and gid is permitted */
283 un_fattr.na_fileid = untab[idx].uid;
284 res.dr_u.dr_drok_u.drok_attributes = un_fattr;
285 memset((char *) &un_fhandle, 0, sizeof(am_nfs_fh));
286 *(u_int *) un_fhandle.fh_data = (u_int) untab[idx].uid;
287 xstrlcpy((char *) &un_fhandle.fh_data[sizeof(int)],
288 untab[idx].username,
289 sizeof(am_nfs_fh) - sizeof(int));
290 res.dr_u.dr_drok_u.drok_fhandle = un_fhandle;
291 res.dr_status = NFS_OK;
292 dlog("nfs_lookup: successful lookup for uid=%ld, gid=%ld: username=%s",
293 (long) uid, (long) gid, untab[idx].username);
294 return &res;
296 } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */
298 res.dr_status = NFSERR_STALE;
299 return &res;
303 nfsreadlinkres *
304 nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
306 static nfsreadlinkres res;
307 uid_t userid = (uid_t) INVALIDID;
308 gid_t groupid = hlfs_gid + 1; /* anything not hlfs_gid */
309 int retval = 0;
310 char *path_val = (char *) NULL;
311 char *username;
312 static uid_t last_uid = (uid_t) INVALIDID;
314 if (eq_fh(argp, &root)) {
315 res.rlr_status = NFSERR_ISDIR;
316 } else if (eq_fh(argp, &slink)) {
317 if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0)
318 return (nfsreadlinkres *) NULL;
320 clocktime(&slinkfattr.na_atime);
322 res.rlr_status = NFS_OK;
323 if (groupid == hlfs_gid) {
324 res.rlr_u.rlr_data_u = DOTSTRING;
325 } else if (!(res.rlr_u.rlr_data_u = path_val = homedir(userid, groupid))) {
327 * parent process (fork in homedir()) continues
328 * processing, by getting a NULL returned as a
329 * "special". Child returns result.
331 return (nfsreadlinkres *) NULL;
334 } else { /* check if asked for user mailbox */
336 if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) {
337 return (nfsreadlinkres *) NULL;
340 if (groupid == hlfs_gid) {
341 memset((char *) &userid, 0, sizeof(int));
342 userid = *(u_int *) argp->fh_data;
343 username = (char *) &argp->fh_data[sizeof(int)];
344 if (!(res.rlr_u.rlr_data_u = mailbox(userid, username)))
345 return (nfsreadlinkres *) NULL;
346 } else {
347 res.rlr_status = NFSERR_STALE;
351 /* print info, but try to avoid repetitions */
352 if (userid != last_uid) {
353 plog(XLOG_USER, "mailbox for uid=%ld, gid=%ld is %s",
354 (long) userid, (long) groupid, (char *) res.rlr_u.rlr_data_u);
355 last_uid = userid;
358 /* I don't think it will pass this if -D fork */
359 if (serverpid == getpid())
360 return &res;
362 if (!svc_sendreply(nfsxprt, (XDRPROC_T_TYPE) xdr_readlinkres, (SVC_IN_ARG_TYPE) &res))
363 svcerr_systemerr(nfsxprt);
366 * Child exists here. We need to determine which
367 * exist status to return. The exit status
368 * is gathered using wait() and determines
369 * if we returned $HOME/.hlfsspool or $ALTDIR. The parent
370 * needs this info so it can update the lookup table.
372 if (path_val && alt_spooldir && STREQ(path_val, alt_spooldir))
373 retval = 1; /* could not get real home dir (or uid 0 user) */
374 else
375 retval = 0;
378 * If asked for -D fork, then must return the value,
379 * NOT exit, or else the main hlfsd server exits.
380 * Bug: where is that status information being collected?
382 if (amuDebug(D_FORK))
383 return &res;
385 exit(retval);
389 nfsreadres *
390 nfsproc_read_2_svc(nfsreadargs *argp, struct svc_req *rqstp)
392 static nfsreadres res = {NFSERR_ACCES};
394 return &res;
398 voidp
399 nfsproc_writecache_2_svc(voidp argp, struct svc_req *rqstp)
401 static char res;
403 return (voidp) &res;
407 nfsattrstat *
408 nfsproc_write_2_svc(nfswriteargs *argp, struct svc_req *rqstp)
410 static nfsattrstat res = {NFSERR_ROFS};
412 return &res;
416 nfsdiropres *
417 nfsproc_create_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
419 static nfsdiropres res = {NFSERR_ROFS};
421 return &res;
425 nfsstat *
426 nfsproc_remove_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
428 static nfsstat res = {NFSERR_ROFS};
430 return &res;
434 nfsstat *
435 nfsproc_rename_2_svc(nfsrenameargs *argp, struct svc_req *rqstp)
437 static nfsstat res = {NFSERR_ROFS};
439 return &res;
443 nfsstat *
444 nfsproc_link_2_svc(nfslinkargs *argp, struct svc_req *rqstp)
446 static nfsstat res = {NFSERR_ROFS};
448 return &res;
452 nfsstat *
453 nfsproc_symlink_2_svc(nfssymlinkargs *argp, struct svc_req *rqstp)
455 static nfsstat res = {NFSERR_ROFS};
457 return &res;
461 nfsdiropres *
462 nfsproc_mkdir_2_svc(nfscreateargs *argp, struct svc_req *rqstp)
464 static nfsdiropres res = {NFSERR_ROFS};
466 return &res;
470 nfsstat *
471 nfsproc_rmdir_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
473 static nfsstat res = {NFSERR_ROFS};
475 return &res;
479 nfsreaddirres *
480 nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp)
482 static nfsreaddirres res;
483 static nfsentry slinkent = {SLINKID, 0, {SLINKCOOKIE}};
484 static nfsentry dotdotent = {ROOTID, "..", {DOTDOTCOOKIE}, &slinkent};
485 static nfsentry dotent = {ROOTID, ".", {DOTCOOKIE}, &dotdotent};
487 slinkent.ne_name = slinkname;
489 if (eq_fh(&argp->rda_fhandle, &slink)) {
490 res.rdr_status = NFSERR_NOTDIR;
491 } else if (eq_fh(&argp->rda_fhandle, &root)) {
492 clocktime(&rootfattr.na_atime);
494 res.rdr_status = NFS_OK;
495 switch (argp->rda_cookie[0]) {
496 case 0:
497 res.rdr_u.rdr_reply_u.dl_entries = &dotent;
498 break;
499 case DOTCOOKIE:
500 res.rdr_u.rdr_reply_u.dl_entries = &dotdotent;
501 break;
502 case DOTDOTCOOKIE:
503 res.rdr_u.rdr_reply_u.dl_entries = &slinkent;
504 break;
505 case SLINKCOOKIE:
506 res.rdr_u.rdr_reply_u.dl_entries = (nfsentry *) 0;
507 break;
509 res.rdr_u.rdr_reply_u.dl_eof = TRUE;
510 } else {
511 res.rdr_status = NFSERR_STALE;
513 return &res;
517 nfsstatfsres *
518 nfsproc_statfs_2_svc(am_nfs_fh *argp, struct svc_req *rqstp)
520 static nfsstatfsres res = {NFS_OK};
522 res.sfr_u.sfr_reply_u.sfrok_tsize = 1024;
523 res.sfr_u.sfr_reply_u.sfrok_bsize = 1024;
526 * Some "df" programs automatically assume that file systems
527 * with zero blocks are meta-filesystems served by automounters.
529 res.sfr_u.sfr_reply_u.sfrok_blocks = 0;
530 res.sfr_u.sfr_reply_u.sfrok_bfree = 0;
531 res.sfr_u.sfr_reply_u.sfrok_bavail = 0;
533 return &res;