home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: nfs_funcs.c
- * Description: The functions of this module are called via RPC from the
- * NFS client. They provide their service based on the functions of
- * 'file_ops.c'. The common interface is defined in 'my_defines.h'.
- * Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at>
- * Date: 1996-11-14
- * Copyright: GNU-GPL
- * Tabsize: 4
- */
-
- #include <libc.h>
- #include <errno.h>
-
- #define NFSCLIENT
- #include <rpc/rpc.h>
- #include "nfs_prot.h"
- #include "my_defines.h"
-
- #define DPRINTF(arg) if(debug_mode & DEBUG_NFS) dprintf arg
- #define NDPRINTF(arg) if(debug_mode & DEBUG_NFS_NOISY) dprintf arg
-
- int nfs_uid;
- int nfs_gid;
- int *nfs_gids;
- int nfs_gidslen; /* gids in nfs_gids */
-
- /* ------------------------------------------------------------------------- */
-
- #define FH(fh) (*(int *)(fh))
- #define FHP(fh) ((int *)(fh))
-
- /* ------------------------------------------------------------------------- */
-
- static void set_ids(struct svc_req *rqstp)
- {
- static int fake_gid = -1;
- 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 = translate_to_disk(IDBUF_USR, unix_cred->aup_uid);
- nfs_gid = translate_to_disk(IDBUF_GRP, unix_cred->aup_gid);
- nfs_gidslen = unix_cred->aup_len;
- nfs_gids = unix_cred->aup_gids;
- for(i=0;i<nfs_gidslen;i++){
- nfs_gids[i] = translate_to_disk(IDBUF_GRP, nfs_gids[i]);
- }
- } else {
- nfs_uid = -1;
- nfs_gid = -1;
- /* Construct a list of one gid. */
- nfs_gidslen = 1;
- nfs_gids = &fake_gid;
- }
- set_current_ids(nfs_uid, nfs_gid);
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void make_nfs_fh(struct nfs_fh *nfs_fh, my_attr_t *ma)
- {
- *(int *)nfs_fh = ma->fileid;
- *((int *)nfs_fh + 1) = (ma->mode & NFSMODE_FMT) ^ NFSMODE_DIR;
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void input_attr(my_attr_t *ma, sattr *sa)
- {
- ma->mode = sa->mode;
- ma->nlink = -1;
- ma->uid = translate_to_disk(IDBUF_USR, sa->uid);
- ma->gid = translate_to_disk(IDBUF_GRP, 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 = translate_to_local(IDBUF_USR, ma->uid);
- fa->gid = translate_to_local(IDBUF_GRP, 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;
- }
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct diropres *nfsproc_create_2(createargs *ca, struct svc_req *rqstp)
- {
- static diropres res;
- my_attr_t fa, sa;
-
- set_ids(rqstp);
- 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_2(dir=%d, name=%s, size=%d)->%d, inode=%d\n",
- FH(&ca->where.dir), ca->where.name, ca->attributes.size,
- res.status, FH(&res.diropres_u.diropres.file)));
- make_nfs_fh(&res.diropres_u.diropres.file, &fa);
- if(res.status == NFS_OK)
- output_attr(&fa, &res.diropres_u.diropres.attributes);
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct diropres *nfsproc_mkdir_2(createargs *ca, struct svc_req *rqstp)
- {
- static diropres res;
- my_attr_t fa, sa;
-
- set_ids(rqstp);
- 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_2(dir=%d, name=%s)->%d, inode=%d\n",
- FH(&ca->where.dir), ca->where.name, res.status,
- FH(&res.diropres_u.diropres.file)));
- make_nfs_fh(&res.diropres_u.diropres.file, &fa);
- if(res.status == NFS_OK)
- output_attr(&fa, &res.diropres_u.diropres.attributes);
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct attrstat *nfsproc_getattr_2(struct nfs_fh *fh, struct svc_req *rqstp)
- {
- static attrstat res;
- my_attr_t fa;
-
- set_ids(rqstp);
- bzero(&res, sizeof(res));
- res.status = nfs_errno(-fo_getattr(&fa, FH(fh)));
- DPRINTF(("nfsproc_getattr_2(fh=%d)->%d\n", FH(fh), res.status));
- if(res.status == NFS_OK)
- output_attr(&fa, &res.attrstat_u.attributes);
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct diropres *nfsproc_lookup_2(diropargs *da, struct svc_req *rqstp)
- {
- static diropres res;
- my_attr_t fa;
-
- set_ids(rqstp);
- 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_2(dir=%d, name=%s)->%d, inode=%d\n",
- FH(&da->dir), da->name, res.status,
- FH(&res.diropres_u.diropres.file)));
- make_nfs_fh(&res.diropres_u.diropres.file, &fa);
- if(res.status == NFS_OK)
- output_attr(&fa, &res.diropres_u.diropres.attributes);
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
-
- struct readdirres *nfsproc_readdir_2(readdirargs *ra, struct svc_req *rqstp)
- {
- static readdirres res;
- struct entry *p, *q;
- int eof, rval;
-
- set_ids(rqstp);
- for(p=res.readdirres_u.reply.entries; p!=NULL; p=q){
- free(p->name);
- q = p->nextentry;
- 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 = nfs_errno(rval < 0 ? -rval : 0);
- res.readdirres_u.reply.eof = eof;
- DPRINTF(("nfsproc_readdir_2(dir=%d, max=%d)->%d, EOF=%d\n",
- FH(&ra->dir), ra->count, res.status, eof));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct attrstat *nfsproc_setattr_2(sattrargs *sa, struct svc_req *rqstp)
- {
- static attrstat res;
- my_attr_t msa, fa;
-
- set_ids(rqstp);
- bzero(&res, sizeof(res));
- input_attr(&msa, &sa->attributes);
- res.status = nfs_errno(-fo_setattr(&fa, FH(&(sa->file)), &msa));
- DPRINTF(("nfsproc_setattr_2(fh=%d)->%d\n", FH(&sa->file), res.status));
- if(res.status == NFS_OK)
- output_attr(&fa, &res.attrstat_u.attributes);
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- nfsstat *nfsproc_remove_2(diropargs *da, struct svc_req *rqstp)
- {
- static nfsstat res;
-
- set_ids(rqstp);
- bzero(&res, sizeof(res));
- res = nfs_errno(-fo_remove(FH(&(da->dir)), da->name));
- DPRINTF(("nfsproc_remove_2(dir=%d, name=%s)->%d\n",
- FH(&da->dir), da->name, res));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- nfsstat *nfsproc_rmdir_2(diropargs *da, struct svc_req *rqstp)
- {
- static nfsstat res;
-
- set_ids(rqstp);
- bzero(&res, sizeof(res));
- res = nfs_errno(-fo_rmdir(FH(&(da->dir)), da->name));
- DPRINTF(("nfsproc_rmdir_2(dir=%d, name=%s)->%d\n",
- FH(&da->dir), da->name, res));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- nfsstat *nfsproc_rename_2(renameargs *ra, struct svc_req *rqstp)
- {
- static nfsstat res;
-
- set_ids(rqstp);
- 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_2(dir=%d, name=%s -> dir=%d, name=%s)->%d\n",
- FH(&ra->from.dir), ra->from.name, FH(&ra->to.dir), ra->to.name, res));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct statfsres *nfsproc_statfs_2(struct nfs_fh *fh, struct svc_req *rqstp)
- {
- static statfsres res;
- my_statfs_t my_stat;
-
- set_ids(rqstp);
- 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_2()->%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;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct readres *nfsproc_read_2(struct readargs *ra, struct svc_req *rqstp)
- {
- static readres res;
- my_attr_t fa;
-
- set_ids(rqstp);
- 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_2(fh=%d, offs=%d, len=%d)->%d, len=%d\n",
- 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;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct attrstat *nfsproc_write_2(writeargs *wa, struct svc_req *rqstp)
- {
- static attrstat res;
- my_attr_t fa;
-
- set_ids(rqstp);
- 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_2(fh=%d, offs=%d, len=%d)->%d, len=%d\n",
- 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;
- }
-
- /* ------------------------------------------------------------------------- */
-
- nfsstat *nfsproc_link_2(linkargs *la, struct svc_req *rqstp)
- {
- static nfsstat res;
-
- set_ids(rqstp);
- bzero(&res, sizeof(res));
- res = nfs_errno(-fo_link(FH(&(la->from)), FH(&(la->to.dir)), la->to.name));
- DPRINTF(("nfsproc_link_2(fh=%d, todir=%d, toname=%s)->%d\n",
- FH(&la->from), FH(&la->to.dir), la->to.name, res));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- struct readlinkres *nfsproc_readlink_2(struct nfs_fh *fh, struct svc_req *rqstp)
- {
- static readlinkres res;
- int rval;
-
- set_ids(rqstp);
- bzero(&res, sizeof(res));
- rval = fo_readlink(&res.readlinkres_u.data, FH(fh));
- res.status = nfs_errno(rval < 0 ? -rval : 0);
- DPRINTF(("nfsproc_readlink_2(fh=%d)->%d, path=%s\n",
- FH(fh), res.status, res.readlinkres_u.data));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- nfsstat *nfsproc_symlink_2(symlinkargs *sa, struct svc_req *rqstp)
- {
- static nfsstat res;
- my_attr_t msa;
-
- set_ids(rqstp);
- 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_2(dir=%d, name=%s, path=%s)->%d\n",
- FH(&sa->from.dir), sa->from.name, sa->to, res));
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- /* Dummy routines */
- void *nfsproc_writecache_2()
- {
- static char res;
-
- eprintf("** nfsproc_writecache_2()\n");
- res = NFSERR_FBIG;
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- void *nfsproc_null_2()
- {
- static char res;
-
- eprintf("** nfsproc_null_2()\n");
- res = NFSERR_FBIG;
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- void *nfsproc_root_2()
- {
- static char res;
-
- eprintf("** nfsproc_root_2()\n");
- res = NFSERR_FBIG;
- return &res;
- }
-
- /* ------------------------------------------------------------------------- */
-