This is nfs_funcs.c in view mode; [Download] [Up]
/* * Name: nfs_funcs.c * Description: This module contains the dispatcher for the nfs server * functions and stubs for these functions. They provide their service * based on the functions of 'fo_nfs.c'. The common interface is * defined in 'my_defines.h'. * Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at> * Date: 1996-12-14 * Copyright: GNU-GPL * Tabsize: 4 */ #define NFSCLIENT #include "syshdr.h" #include <rpc/rpc.h> #include "my_defines.h" #include "nfs_prot.h" #define DPRINTF(arg) if(debug_mode & DEBUG_NFS) dprintf arg #define NDPRINTF(arg) if(debug_mode & DEBUG_NFS_NOISY) dprintf arg #define NFS_MAX_GROUPS 50 int nfs_uid; int nfs_gid; short nfs_gids[NFS_MAX_GROUPS]; int nfs_gidslen; /* gids in nfs_gids */ /* ------------------------------------------------------------------------- */ #define FH(fh) (*(fh_t *)(fh)) #define FHP(fh) ((fh_t *)(fh)) /* ------------------------------------------------------------------------- */ static inline void set_ids(struct svc_req *rqstp) { #if 0 /* currently no authentication used */ int i; if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) { struct authunix_parms *unix_cred; unix_cred = (struct authunix_parms *) rqstp->rq_clntcred; nfs_uid = unix_cred->aup_uid; nfs_gid = unix_cred->aup_gid; nfs_gidslen = unix_cred->aup_len > NFS_MAX_GROUPS ? NFS_MAX_GROUPS : unix_cred->aup_len; for(i=0;i<nfs_gidslen;i++) nfs_gids[i] = unix_cred->aup_gids[i]; } else { nfs_uid = -1; nfs_gid = -1; /* Construct a list of one gid. */ nfs_gidslen = 1; nfs_gids[0] = -1; } /* set_current_ids(nfs_uid, nfs_gid);*/ #endif } /* ------------------------------------------------------------------------- */ static void input_attr(my_attr_t *ma, sattr *sa) { ma->mode = sa->mode; ma->nlink = -1; ma->uid = sa->uid; ma->gid = sa->gid; ma->size = sa->size; ma->blocksize = -1; ma->blocks = -1; ma->fileid = -1; ma->atime = sa->atime.seconds; /* ignored in lower level */ ma->mtime = sa->mtime.seconds; ma->ctime = -1; } /* ------------------------------------------------------------------------- */ static void output_attr(my_attr_t *ma, fattr *fa) { fa->type = NFNON; if((ma->mode & NFSMODE_FMT) == NFSMODE_DIR) fa->type = NFDIR; else if((ma->mode & NFSMODE_FMT) == NFSMODE_REG) fa->type = NFREG; else if((ma->mode & NFSMODE_FMT) == NFSMODE_LNK) fa->type = NFLNK; else if((ma->mode & NFSMODE_FMT) == NFSMODE_CHR) fa->type = NFCHR; else if((ma->mode & NFSMODE_FMT) == NFSMODE_BLK) fa->type = NFBLK; else if((ma->mode & NFSMODE_FMT) == NFSMODE_SOCK) fa->type = NFSOCK; else if((ma->mode & NFSMODE_FMT) == NFSMODE_FIFO) fa->type = NFFIFO; else{ eprintf("** output_attr(): file type unknown: mode=0%o\n", ma->mode); } fa->mode = ma->mode; fa->nlink = ma->nlink; fa->uid = ma->uid; fa->gid = ma->gid; fa->size = ma->size; fa->blocksize = ma->blocksize; fa->blocks = ma->blocks; fa->fsid = 562654; /* dummy non zero value */ fa->fileid = ma->fileid; fa->atime.seconds = ma->atime; fa->mtime.seconds = ma->mtime; fa->ctime.seconds = ma->ctime; fa->rdev = ma->rdev; NDPRINTF(("output_attr(): attributes are:\n")); NDPRINTF((" type = %d\n", fa->type)); NDPRINTF((" mode = 0%o\n", fa->mode)); NDPRINTF((" nlink = %d\n", fa->nlink)); NDPRINTF((" uid = %d\n", fa->uid)); NDPRINTF((" gid = %d\n", fa->gid)); NDPRINTF((" size = %d\n", fa->size)); NDPRINTF((" blocksize = %d\n", fa->blocksize)); NDPRINTF((" blocks = %d\n", fa->blocks)); NDPRINTF((" fileid = %d\n", fa->fileid)); } /* ------------------------------------------------------------------------- */ static int nfs_errno(int sys_errno) { switch(sys_errno){ case 0: return NFS_OK; case EPERM: return NFSERR_PERM; case ENOENT: return NFSERR_NOENT; case ENXIO: return NFSERR_NXIO; case ETXTBSY: case EWOULDBLOCK: case EACCES: return NFSERR_ACCES; case EEXIST: return NFSERR_EXIST; case ENODEV: return NFSERR_NODEV; case ENOTDIR: return NFSERR_NOTDIR; case EISDIR: return NFSERR_ISDIR; case E2BIG: case EFBIG: return NFSERR_FBIG; case ENOSPC: return NFSERR_NOSPC; case EROFS: return NFSERR_ROFS; case ENAMETOOLONG: return NFSERR_NAMETOOLONG; case ENOTEMPTY: return NFSERR_NOTEMPTY; case EDQUOT: return NFSERR_DQUOT; case MY_NFSERR_STALE: return NFSERR_STALE; default: /* this is general enough for a reasonable error default */ return NFSERR_IO; } } /* ------------------------------------------------------------------------- */ static struct diropres *nfsproc_create(createargs *ca) { static diropres res; my_attr_t fa, sa; bzero(&res, sizeof(res)); input_attr(&sa, &ca->attributes); res.status = nfs_errno(-fo_create(FHP(&res.diropres_u.diropres.file), &fa, FH(&ca->where.dir), ca->where.name, &sa)); DPRINTF(("nfsproc_create(dir=%d, name=%s, size=%d)->%d, inode=%d\n", (int)FH(&ca->where.dir), ca->where.name, ca->attributes.size, res.status, (int)FH(&res.diropres_u.diropres.file))); if(res.status == NFS_OK) output_attr(&fa, &res.diropres_u.diropres.attributes); return &res; } /* ------------------------------------------------------------------------- */ static struct diropres *nfsproc_mkdir(createargs *ca) { static diropres res; my_attr_t fa, sa; bzero(&res, sizeof(res)); input_attr(&sa, &ca->attributes); res.status = nfs_errno(-fo_mkdir(FHP(&res.diropres_u.diropres.file), &fa, FH(&(ca->where.dir)), ca->where.name, &sa)); DPRINTF(("nfsproc_mkdir(dir=%d, name=%s)->%d, inode=%d\n", (int)FH(&ca->where.dir), ca->where.name, res.status, (int)FH(&res.diropres_u.diropres.file))); if(res.status == NFS_OK) output_attr(&fa, &res.diropres_u.diropres.attributes); return &res; } /* ------------------------------------------------------------------------- */ static struct attrstat *nfsproc_getattr(struct nfs_fh *fh) { static attrstat res; my_attr_t fa; bzero(&res, sizeof(res)); res.status = nfs_errno(-fo_getattr(&fa, FH(fh))); DPRINTF(("nfsproc_getattr(fh=%d)->%d\n", (int)FH(fh), res.status)); if(res.status == NFS_OK) output_attr(&fa, &res.attrstat_u.attributes); return &res; } /* ------------------------------------------------------------------------- */ static struct diropres *nfsproc_lookup(diropargs *da) { static diropres res; my_attr_t fa; bzero(&res, sizeof(res)); res.status = nfs_errno(-fo_lookup(FHP(&res.diropres_u.diropres.file), &fa, FH(&(da->dir)), da->name)); DPRINTF(("nfsproc_lookup(dir=%d, name=%s)->%d, inode=%d\n", (int)FH(&da->dir), da->name, res.status, (int)FH(&res.diropres_u.diropres.file))); if(res.status == NFS_OK) output_attr(&fa, &res.diropres_u.diropres.attributes); return &res; } /* ------------------------------------------------------------------------- */ static struct readdirres *nfsproc_readdir(readdirargs *ra) { static readdirres res; struct entry *p, *q; int eof, rval; for(p=res.readdirres_u.reply.entries; p!=NULL; p=q){ q = p->nextentry; free(p->name); free(p); } bzero(&res, sizeof(res)); rval = fo_readdir((my_direntry_t **)&res.readdirres_u.reply.entries, &eof, ra->count, FH(&(ra->dir)), ntohl(*(int *)(ra->cookie))); for(p=res.readdirres_u.reply.entries; p!=NULL; p=p->nextentry){ *(int *)p->cookie = htonl(*(int *)p->cookie); } res.status = rval < 0 ? nfs_errno(-rval) : NFS_OK; res.readdirres_u.reply.eof = eof; DPRINTF(("nfsproc_readdir(dir=%d, max=%d)->%d, EOF=%d\n", (int)FH(&ra->dir), ra->count, res.status, eof)); return &res; } /* ------------------------------------------------------------------------- */ static struct attrstat *nfsproc_setattr(sattrargs *sa) { static attrstat res; my_attr_t msa, fa; bzero(&res, sizeof(res)); input_attr(&msa, &sa->attributes); res.status = nfs_errno(-fo_setattr(&fa, FH(&(sa->file)), &msa)); DPRINTF(("nfsproc_setattr(fh=%d)->%d\n", (int)FH(&sa->file),res.status)); if(res.status == NFS_OK) output_attr(&fa, &res.attrstat_u.attributes); return &res; } /* ------------------------------------------------------------------------- */ static nfsstat *nfsproc_remove(diropargs *da) { static nfsstat res; bzero(&res, sizeof(res)); res = nfs_errno(-fo_remove(FH(&(da->dir)), da->name)); DPRINTF(("nfsproc_remove(dir=%d, name=%s)->%d\n", (int)FH(&da->dir), da->name, res)); return &res; } /* ------------------------------------------------------------------------- */ static nfsstat *nfsproc_rmdir(diropargs *da) { static nfsstat res; bzero(&res, sizeof(res)); res = nfs_errno(-fo_rmdir(FH(&(da->dir)), da->name)); DPRINTF(("nfsproc_rmdir(dir=%d, name=%s)->%d\n", (int)FH(&da->dir), da->name, res)); return &res; } /* ------------------------------------------------------------------------- */ static nfsstat *nfsproc_rename(renameargs *ra) { static nfsstat res; bzero(&res, sizeof(res)); res = nfs_errno(-fo_rename(FH(&(ra->from.dir)), ra->from.name, FH(&(ra->to.dir)), ra->to.name)); DPRINTF(("nfsproc_rename(dir=%d, name=%s -> dir=%d, name=%s)->%d\n", (int)FH(&ra->from.dir), ra->from.name, (int)FH(&ra->to.dir), ra->to.name, res)); return &res; } /* ------------------------------------------------------------------------- */ static struct statfsres *nfsproc_statfs(struct nfs_fh *fh) { static statfsres res; my_statfs_t my_stat; bzero(&res, sizeof(res)); res.status = nfs_errno(-fo_statfs(&my_stat)); res.statfsres_u.reply.tsize = 32768; res.statfsres_u.reply.bsize = my_stat.bsize; res.statfsres_u.reply.blocks = my_stat.blocks; res.statfsres_u.reply.bfree = my_stat.bfree; res.statfsres_u.reply.bavail = my_stat.bavail; DPRINTF(("nfsproc_statfs()->%d\n", res.status)); DPRINTF(("bsize=%ld blocks=%ld free=%ld avail=%ld\n", my_stat.bsize, my_stat.blocks, my_stat.bfree, my_stat.bavail)); return &res; } /* ------------------------------------------------------------------------- */ static struct readres *nfsproc_read(struct readargs *ra) { static readres res; my_attr_t fa; bzero(&res, sizeof(res)); res.status = nfs_errno(-fo_read(&fa, &res.readres_u.reply.data.data_len, &res.readres_u.reply.data.data_val, FH(&(ra->file)), ra->offset, ra->count)); DPRINTF(("nfsproc_read(fh=%d, offs=%d, len=%d)->%d, len=%d\n", (int)FH(&ra->file), (int)ra->offset, (int)ra->count, res.status, (int)res.readres_u.reply.data.data_len)); if(res.status == NFS_OK) output_attr(&fa, &res.readres_u.reply.attributes); return &res; } /* ------------------------------------------------------------------------- */ static struct attrstat *nfsproc_write(writeargs *wa) { static attrstat res; my_attr_t fa; bzero(&res, sizeof(res)); res.status = nfs_errno(-fo_write(&fa, FH(&(wa->file)), wa->offset, wa->data.data_len, wa->data.data_val)); DPRINTF(("nfsproc_write(fh=%d, offs=%d, len=%d)->%d, len=%d\n", (int)FH(&wa->file), (int)wa->offset, (int)wa->data.data_len, res.status, fa.size)); if(res.status == NFS_OK) output_attr(&fa, &res.attrstat_u.attributes); return &res; } /* ------------------------------------------------------------------------- */ static nfsstat *nfsproc_link(linkargs *la) { static nfsstat res; bzero(&res, sizeof(res)); res = nfs_errno(-fo_link(FH(&(la->from)), FH(&(la->to.dir)), la->to.name)); DPRINTF(("nfsproc_link(fh=%d, todir=%d, toname=%s)->%d\n", (int)FH(&la->from), (int)FH(&la->to.dir), la->to.name, res)); return &res; } /* ------------------------------------------------------------------------- */ static struct readlinkres *nfsproc_readlink(struct nfs_fh *fh) { static readlinkres res; int rval; bzero(&res, sizeof(res)); rval = fo_readlink(&res.readlinkres_u.data, FH(fh)); res.status = rval < 0 ? nfs_errno(-rval) : NFS_OK; DPRINTF(("nfsproc_readlink(fh=%d)->%d, path=%s\n", (int)FH(fh), res.status, res.readlinkres_u.data)); return &res; } /* ------------------------------------------------------------------------- */ static nfsstat *nfsproc_symlink(symlinkargs *sa) { static nfsstat res; my_attr_t msa; bzero(&res, sizeof(res)); input_attr(&msa, &sa->attributes); res = nfs_errno(-fo_symlink(FH(&sa->from.dir), sa->from.name,sa->to,&msa)); DPRINTF(("nfsproc_symlink(dir=%d, name=%s, path=%s)->%d\n", (int)FH(&sa->from.dir), sa->from.name, sa->to, res)); return &res; } /* ------------------------------------------------------------------------- */ /* Dummy routines */ static void *nfsproc_writecache() { static nfsstat res; eprintf("** nfsproc_writecache()\n"); res = NFSERR_FBIG; return &res; } /* ------------------------------------------------------------------------- */ static void *nfsproc_null() { static nfsstat res; eprintf("** nfsproc_null()\n"); res = NFSERR_FBIG; return &res; } /* ------------------------------------------------------------------------- */ static void *nfsproc_root() { static nfsstat res; eprintf("** nfsproc_root()\n"); res = NFSERR_FBIG; return &res; } /* ------------------------------------------------------------------------- */ #define ENTRY(res_type, arg_type, funct) { \ sizeof(res_type), sizeof(arg_type), \ xdr_##res_type, xdr_##arg_type, \ (void *(*)())nfsproc_##funct, #funct \ } #define nil char #define xdr_nil xdr_void struct dentry { int res_size, arg_size; /* sizeof the res/arg structs */ bool_t (*xdr_result)(); bool_t (*xdr_argument)(); void *(*function)(); /* function handler */ char *name; /* name of function */ }; /* ------------------------------------------------------------------------- */ static struct dentry dispatch_table[] = { ENTRY(nil, nil, null), /* NULL */ ENTRY(attrstat, nfs_fh, getattr), /* GETATTR */ ENTRY(attrstat, sattrargs, setattr), /* SETATTR */ ENTRY(nil, nil, root), /* ROOT */ ENTRY(diropres, diropargs, lookup), /* LOOKUP */ ENTRY(readlinkres, nfs_fh, readlink), /* READLINK */ ENTRY(readres, readargs, read), /* READ */ ENTRY(nil, nil, writecache), /* WRITECACHE */ ENTRY(attrstat, writeargs, write), /* WRITE */ ENTRY(diropres, createargs, create), /* CREATE */ ENTRY(nfsstat, diropargs, remove), /* REMOVE */ ENTRY(nfsstat, renameargs, rename), /* RENAME */ ENTRY(nfsstat, linkargs, link), /* LINK */ ENTRY(nfsstat, symlinkargs, symlink), /* SYMLINK */ ENTRY(diropres, createargs, mkdir), /* MKDIR */ ENTRY(nfsstat, diropargs, rmdir), /* RMDIR */ ENTRY(readdirres, readdirargs, readdir),/* READDIR */ ENTRY(statfsres, nfs_fh, statfs), /* STATFS */ }; /* ------------------------------------------------------------------------- */ void nfs_dispatch(struct svc_req *rqstp, SVCXPRT *transp) { unsigned int proc_i = rqstp->rq_proc; struct dentry *dent; void *result; union { nfs_fh nfsproc_getattr_2_arg; sattrargs nfsproc_setattr_2_arg; diropargs nfsproc_lookup_2_arg; nfs_fh nfsproc_readlink_2_arg; readargs nfsproc_read_2_arg; writeargs nfsproc_write_2_arg; createargs nfsproc_create_2_arg; diropargs nfsproc_remove_2_arg; renameargs nfsproc_rename_2_arg; linkargs nfsproc_link_2_arg; symlinkargs nfsproc_symlink_2_arg; createargs nfsproc_mkdir_2_arg; diropargs nfsproc_rmdir_2_arg; readdirargs nfsproc_readdir_2_arg; nfs_fh nfsproc_statfs_2_arg; } argument; if (proc_i >= (sizeof(dispatch_table) / sizeof(struct entry))){ svcerr_noproc(transp); DPRINTF(("nfs_dispatch(): illegal procedure %d\n", proc_i)); return; } dent = &dispatch_table[proc_i]; bzero(&argument, dent->arg_size); if (!svc_getargs(transp, dent->xdr_argument, &argument)){ svcerr_decode(transp); DPRINTF(("nfs_dispatch(): error decoding arguments for %d\n", proc_i)); return; } set_ids(rqstp); result = (*dent->function) (&argument); if (result != NULL && !svc_sendreply(transp, dent->xdr_result, result)){ svcerr_systemerr(transp); } if (!svc_freeargs(transp, dent->xdr_argument, &argument)){ eprintf("nfs_dispatch: unable to free arguments\n"); terminate(1); } } /* ------------------------------------------------------------------------- */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.