home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Utilities / vmount-0.6a-I / src / nfs / nfs_funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-30  |  13.8 KB  |  502 lines

  1. /*
  2.  * Name: nfs_funcs.c
  3.  * Description: The functions of this module are called via RPC from the
  4.  *     NFS client. They provide their service based on the functions of
  5.  *     'file_ops.c'. The common interface is defined in 'my_defines.h'.
  6.  * Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at>
  7.  * Date: 1996-11-14
  8.  * Copyright: GNU-GPL
  9.  * Tabsize: 4
  10.  */
  11.  
  12. #include <libc.h>
  13. #include <errno.h>
  14.  
  15. #define NFSCLIENT
  16. #include <rpc/rpc.h>
  17. #include "nfs_prot.h"
  18. #include "my_defines.h"
  19.  
  20. #define    DPRINTF(arg)    if(debug_mode &    DEBUG_NFS)            dprintf arg
  21. #define    NDPRINTF(arg)    if(debug_mode &    DEBUG_NFS_NOISY)    dprintf arg
  22.  
  23. int        nfs_uid;
  24. int        nfs_gid;
  25. int        *nfs_gids;
  26. int        nfs_gidslen;    /* gids in nfs_gids */
  27.  
  28. /* ------------------------------------------------------------------------- */
  29.  
  30. #define    FH(fh)    (*(int *)(fh))
  31. #define    FHP(fh)    ((int *)(fh))
  32.  
  33. /* ------------------------------------------------------------------------- */
  34.  
  35. static void    set_ids(struct svc_req *rqstp)
  36. {
  37. static int    fake_gid = -1;
  38. int            i;
  39.  
  40.     if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
  41.         struct authunix_parms *unix_cred;
  42.         unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
  43.         nfs_uid = translate_to_disk(IDBUF_USR, unix_cred->aup_uid);
  44.         nfs_gid = translate_to_disk(IDBUF_GRP, unix_cred->aup_gid);
  45.         nfs_gidslen = unix_cred->aup_len;
  46.         nfs_gids = unix_cred->aup_gids;
  47.         for(i=0;i<nfs_gidslen;i++){
  48.             nfs_gids[i] = translate_to_disk(IDBUF_GRP, nfs_gids[i]);
  49.         }
  50.     } else {
  51.         nfs_uid = -1;
  52.         nfs_gid = -1;
  53.         /* Construct a list of one gid. */
  54.         nfs_gidslen = 1;
  55.         nfs_gids = &fake_gid;
  56.     }
  57.     set_current_ids(nfs_uid, nfs_gid);
  58. }
  59.  
  60. /* ------------------------------------------------------------------------- */
  61.  
  62. static void    make_nfs_fh(struct nfs_fh *nfs_fh, my_attr_t *ma)
  63. {
  64.     *(int *)nfs_fh = ma->fileid;
  65.     *((int *)nfs_fh + 1) = (ma->mode & NFSMODE_FMT) ^ NFSMODE_DIR;
  66. }
  67.  
  68. /* ------------------------------------------------------------------------- */
  69.  
  70. static void    input_attr(my_attr_t *ma, sattr *sa)
  71. {
  72.     ma->mode = sa->mode;
  73.     ma->nlink = -1;
  74.     ma->uid = translate_to_disk(IDBUF_USR, sa->uid);
  75.     ma->gid = translate_to_disk(IDBUF_GRP, sa->gid);
  76.     ma->size = sa->size;
  77.     ma->blocksize = -1;
  78.     ma->blocks = -1;
  79.     ma->fileid = -1;
  80.     ma->atime = sa->atime.seconds;    /* ignored in lower level */
  81.     ma->mtime = sa->mtime.seconds;
  82.     ma->ctime = -1;
  83. }
  84.  
  85. /* ------------------------------------------------------------------------- */
  86.  
  87. static void    output_attr(my_attr_t *ma, fattr *fa)
  88. {
  89.     fa->type = NFNON;
  90.     if((ma->mode & NFSMODE_FMT) == NFSMODE_DIR)
  91.         fa->type = NFDIR;
  92.     else if((ma->mode & NFSMODE_FMT) == NFSMODE_REG)
  93.         fa->type = NFREG;
  94.     else if((ma->mode & NFSMODE_FMT) == NFSMODE_LNK)
  95.         fa->type = NFLNK;
  96.     else if((ma->mode & NFSMODE_FMT) == NFSMODE_CHR)
  97.         fa->type = NFCHR;
  98.     else if((ma->mode & NFSMODE_FMT) == NFSMODE_BLK)
  99.         fa->type = NFBLK;
  100.     else if((ma->mode & NFSMODE_FMT) == NFSMODE_SOCK)
  101.         fa->type = NFSOCK;
  102.     else if((ma->mode & NFSMODE_FMT) == NFSMODE_FIFO)
  103.         fa->type = NFFIFO;
  104.     else{
  105.         eprintf("** output_attr(): file type unknown: mode=0%o\n", ma->mode);
  106.     }
  107.     fa->mode = ma->mode;
  108.     fa->nlink = ma->nlink;
  109.     fa->uid = translate_to_local(IDBUF_USR, ma->uid);
  110.     fa->gid = translate_to_local(IDBUF_GRP, ma->gid);
  111.     fa->size = ma->size;
  112.     fa->blocksize = ma->blocksize;
  113.     fa->blocks = ma->blocks;
  114.     fa->fsid = 562654;    /* dummy non zero value */
  115.     fa->fileid = ma->fileid;
  116.     fa->atime.seconds = ma->atime;
  117.     fa->mtime.seconds = ma->mtime;
  118.     fa->ctime.seconds = ma->ctime;
  119.     fa->rdev = ma->rdev;
  120.     NDPRINTF(("output_attr(): attributes are:\n"));
  121.     NDPRINTF(("  type      = %d\n", fa->type));
  122.     NDPRINTF(("  mode      = 0%o\n", fa->mode));
  123.     NDPRINTF(("  nlink     = %d\n", fa->nlink));
  124.     NDPRINTF(("  uid       = %d\n", fa->uid));
  125.     NDPRINTF(("  gid       = %d\n", fa->gid));
  126.     NDPRINTF(("  size      = %d\n", fa->size));
  127.     NDPRINTF(("  blocksize = %d\n", fa->blocksize));
  128.     NDPRINTF(("  blocks    = %d\n", fa->blocks));
  129.     NDPRINTF(("  fileid    = %d\n", fa->fileid));
  130. }
  131.  
  132. /* ------------------------------------------------------------------------- */
  133.  
  134. static int    nfs_errno(int sys_errno)
  135. {
  136.     switch(sys_errno){
  137.     case 0:
  138.         return NFS_OK;
  139.     case EPERM:
  140.         return NFSERR_PERM;
  141.     case ENOENT:
  142.         return NFSERR_NOENT;
  143.     case ENXIO:
  144.         return NFSERR_NXIO;
  145.     case ETXTBSY:
  146.     case EWOULDBLOCK:
  147.     case EACCES:
  148.         return NFSERR_ACCES;
  149.     case EEXIST:
  150.         return NFSERR_EXIST;
  151.     case ENODEV:
  152.         return NFSERR_NODEV;
  153.     case ENOTDIR:
  154.         return NFSERR_NOTDIR;
  155.     case EISDIR:
  156.         return NFSERR_ISDIR;
  157.     case E2BIG:
  158.     case EFBIG:
  159.         return NFSERR_FBIG;
  160.     case ENOSPC:
  161.         return NFSERR_NOSPC;
  162.     case EROFS:
  163.         return NFSERR_ROFS;
  164.     case ENAMETOOLONG:
  165.         return NFSERR_NAMETOOLONG;
  166.     case ENOTEMPTY:
  167.         return NFSERR_NOTEMPTY;
  168.     case EDQUOT:
  169.         return NFSERR_DQUOT;
  170.     case MY_NFSERR_STALE:
  171.         return NFSERR_STALE;
  172.     default:    /* this is general enough for a reasonable error default */
  173.         return NFSERR_IO;
  174.     }
  175. }
  176.  
  177. /* ------------------------------------------------------------------------- */
  178.  
  179. struct diropres    *nfsproc_create_2(createargs *ca, struct svc_req *rqstp)
  180. {
  181. static diropres res;
  182. my_attr_t    fa, sa;
  183.  
  184.     set_ids(rqstp);
  185.     bzero(&res, sizeof(res));
  186.     input_attr(&sa, &ca->attributes);
  187.     res.status = nfs_errno(-fo_create(FHP(&res.diropres_u.diropres.file),
  188.                             &fa,
  189.                             FH(&ca->where.dir),
  190.                             ca->where.name,
  191.                             &sa));
  192.     DPRINTF(("nfsproc_create_2(dir=%d, name=%s, size=%d)->%d, inode=%d\n",
  193.                 FH(&ca->where.dir), ca->where.name, ca->attributes.size,
  194.                 res.status, FH(&res.diropres_u.diropres.file)));
  195.     make_nfs_fh(&res.diropres_u.diropres.file, &fa);
  196.     if(res.status == NFS_OK)
  197.         output_attr(&fa, &res.diropres_u.diropres.attributes);
  198.     return &res;
  199. }
  200.  
  201. /* ------------------------------------------------------------------------- */
  202.  
  203. struct diropres    *nfsproc_mkdir_2(createargs *ca, struct svc_req *rqstp)
  204. {
  205. static diropres res;
  206. my_attr_t        fa, sa;
  207.  
  208.     set_ids(rqstp);
  209.     bzero(&res, sizeof(res));
  210.     input_attr(&sa, &ca->attributes);
  211.     res.status = nfs_errno(-fo_mkdir(FHP(&res.diropres_u.diropres.file),
  212.                             &fa,
  213.                             FH(&(ca->where.dir)),
  214.                             ca->where.name,
  215.                             &sa));
  216.     DPRINTF(("nfsproc_mkdir_2(dir=%d, name=%s)->%d, inode=%d\n",
  217.                 FH(&ca->where.dir), ca->where.name, res.status,
  218.                 FH(&res.diropres_u.diropres.file)));
  219.     make_nfs_fh(&res.diropres_u.diropres.file, &fa);
  220.     if(res.status == NFS_OK)
  221.         output_attr(&fa, &res.diropres_u.diropres.attributes);
  222.     return &res;
  223. }
  224.  
  225. /* ------------------------------------------------------------------------- */
  226.  
  227. struct attrstat *nfsproc_getattr_2(struct nfs_fh *fh, struct svc_req *rqstp)
  228. {
  229. static attrstat    res;
  230. my_attr_t        fa;
  231.  
  232.     set_ids(rqstp);
  233.     bzero(&res, sizeof(res));
  234.     res.status = nfs_errno(-fo_getattr(&fa, FH(fh)));
  235.     DPRINTF(("nfsproc_getattr_2(fh=%d)->%d\n", FH(fh), res.status));
  236.     if(res.status == NFS_OK)
  237.         output_attr(&fa, &res.attrstat_u.attributes);
  238.     return &res;
  239. }
  240.  
  241. /* ------------------------------------------------------------------------- */
  242.  
  243. struct diropres *nfsproc_lookup_2(diropargs *da, struct svc_req *rqstp)
  244. {
  245. static diropres res;
  246. my_attr_t        fa;
  247.  
  248.     set_ids(rqstp);
  249.     bzero(&res, sizeof(res));
  250.     res.status = nfs_errno(-fo_lookup(FHP(&res.diropres_u.diropres.file),
  251.                             &fa,
  252.                             FH(&(da->dir)),
  253.                             da->name));
  254.     DPRINTF(("nfsproc_lookup_2(dir=%d, name=%s)->%d, inode=%d\n",
  255.                 FH(&da->dir), da->name, res.status,
  256.                 FH(&res.diropres_u.diropres.file)));
  257.     make_nfs_fh(&res.diropres_u.diropres.file, &fa);
  258.     if(res.status == NFS_OK)
  259.         output_attr(&fa, &res.diropres_u.diropres.attributes);
  260.     return &res;
  261. }
  262.  
  263. /* ------------------------------------------------------------------------- */
  264.  
  265.  
  266. struct readdirres *nfsproc_readdir_2(readdirargs *ra, struct svc_req *rqstp)
  267. {
  268. static readdirres        res;
  269. struct entry            *p, *q;
  270. int                        eof, rval;
  271.  
  272.     set_ids(rqstp);
  273.     for(p=res.readdirres_u.reply.entries; p!=NULL; p=q){
  274.         free(p->name);
  275.         q = p->nextentry;
  276.         free(p);
  277.     }
  278.     bzero(&res, sizeof(res));
  279.     rval = fo_readdir((my_direntry_t **)&res.readdirres_u.reply.entries,
  280.                             &eof,
  281.                             ra->count,
  282.                             FH(&(ra->dir)),
  283.                             ntohl(*(int *)(ra->cookie)));
  284.     for(p=res.readdirres_u.reply.entries; p!=NULL; p=p->nextentry){
  285.         *(int *)p->cookie = htonl(*(int *)p->cookie);
  286.     }
  287.     res.status = nfs_errno(rval < 0 ? -rval : 0);
  288.     res.readdirres_u.reply.eof = eof;
  289.     DPRINTF(("nfsproc_readdir_2(dir=%d, max=%d)->%d, EOF=%d\n",
  290.                                 FH(&ra->dir), ra->count, res.status, eof));
  291.     return &res;
  292. }
  293.  
  294. /* ------------------------------------------------------------------------- */
  295.  
  296. struct attrstat *nfsproc_setattr_2(sattrargs *sa, struct svc_req *rqstp)
  297. {
  298. static attrstat    res;
  299. my_attr_t        msa, fa;
  300.  
  301.     set_ids(rqstp);
  302.     bzero(&res, sizeof(res));
  303.     input_attr(&msa, &sa->attributes);
  304.     res.status = nfs_errno(-fo_setattr(&fa, FH(&(sa->file)), &msa));
  305.     DPRINTF(("nfsproc_setattr_2(fh=%d)->%d\n", FH(&sa->file), res.status));
  306.     if(res.status == NFS_OK)
  307.         output_attr(&fa, &res.attrstat_u.attributes);
  308.     return &res;
  309. }
  310.  
  311. /* ------------------------------------------------------------------------- */
  312.  
  313. nfsstat *nfsproc_remove_2(diropargs *da, struct svc_req *rqstp)
  314. {
  315. static nfsstat    res;
  316.  
  317.     set_ids(rqstp);
  318.     bzero(&res, sizeof(res));
  319.     res = nfs_errno(-fo_remove(FH(&(da->dir)), da->name));
  320.     DPRINTF(("nfsproc_remove_2(dir=%d, name=%s)->%d\n",
  321.                                             FH(&da->dir), da->name, res));
  322.     return &res;
  323. }
  324.  
  325. /* ------------------------------------------------------------------------- */
  326.  
  327. nfsstat *nfsproc_rmdir_2(diropargs *da, struct svc_req *rqstp)
  328. {
  329. static nfsstat    res;
  330.  
  331.     set_ids(rqstp);
  332.     bzero(&res, sizeof(res));
  333.     res = nfs_errno(-fo_rmdir(FH(&(da->dir)), da->name));
  334.     DPRINTF(("nfsproc_rmdir_2(dir=%d, name=%s)->%d\n",
  335.                                             FH(&da->dir), da->name, res));
  336.     return &res;
  337. }
  338.  
  339. /* ------------------------------------------------------------------------- */
  340.  
  341. nfsstat *nfsproc_rename_2(renameargs *ra, struct svc_req *rqstp)
  342. {
  343. static nfsstat    res;
  344.  
  345.     set_ids(rqstp);
  346.     bzero(&res, sizeof(res));
  347.     res = nfs_errno(-fo_rename(FH(&(ra->from.dir)), ra->from.name,
  348.                     FH(&(ra->to.dir)), ra->to.name));
  349.     DPRINTF(("nfsproc_rename_2(dir=%d, name=%s -> dir=%d, name=%s)->%d\n",
  350.         FH(&ra->from.dir), ra->from.name, FH(&ra->to.dir), ra->to.name, res));
  351.     return &res;
  352. }
  353.  
  354. /* ------------------------------------------------------------------------- */
  355.  
  356. struct statfsres *nfsproc_statfs_2(struct nfs_fh *fh, struct svc_req *rqstp)
  357. {
  358. static statfsres    res;
  359. my_statfs_t            my_stat;
  360.  
  361.     set_ids(rqstp);
  362.     bzero(&res, sizeof(res));
  363.     res.status = nfs_errno(-fo_statfs(&my_stat));
  364.     res.statfsres_u.reply.tsize = 32768;
  365.     res.statfsres_u.reply.bsize = my_stat.bsize;
  366.     res.statfsres_u.reply.blocks = my_stat.blocks;
  367.     res.statfsres_u.reply.bfree = my_stat.bfree;
  368.     res.statfsres_u.reply.bavail = my_stat.bavail;
  369.     DPRINTF(("nfsproc_statfs_2()->%d\n", res.status));
  370.     DPRINTF(("bsize=%ld blocks=%ld free=%ld avail=%ld\n",
  371.         my_stat.bsize, my_stat.blocks, my_stat.bfree, my_stat.bavail));
  372.     return &res;
  373. }
  374.  
  375. /* ------------------------------------------------------------------------- */
  376.  
  377. struct readres *nfsproc_read_2(struct readargs *ra, struct svc_req *rqstp)
  378. {
  379. static readres    res;
  380. my_attr_t        fa;
  381.  
  382.     set_ids(rqstp);
  383.     bzero(&res, sizeof(res));
  384.     res.status = nfs_errno(-fo_read(&fa,
  385.                         &res.readres_u.reply.data.data_len,
  386.                         &res.readres_u.reply.data.data_val,
  387.                         FH(&(ra->file)),
  388.                         ra->offset,
  389.                         ra->count));
  390.     DPRINTF(("nfsproc_read_2(fh=%d, offs=%d, len=%d)->%d, len=%d\n",
  391.                 FH(&ra->file), (int)ra->offset, (int)ra->count, res.status,
  392.                 (int)res.readres_u.reply.data.data_len));
  393.     if(res.status == NFS_OK)
  394.         output_attr(&fa, &res.readres_u.reply.attributes);
  395.     return &res;
  396. }
  397.  
  398. /* ------------------------------------------------------------------------- */
  399.  
  400. struct attrstat *nfsproc_write_2(writeargs *wa, struct svc_req *rqstp)
  401. {
  402. static attrstat    res;
  403. my_attr_t        fa;
  404.  
  405.     set_ids(rqstp);
  406.     bzero(&res, sizeof(res));
  407.     res.status = nfs_errno(-fo_write(&fa,
  408.                         FH(&(wa->file)),
  409.                         wa->offset,
  410.                         wa->data.data_len,
  411.                         wa->data.data_val));
  412.     DPRINTF(("nfsproc_write_2(fh=%d, offs=%d, len=%d)->%d, len=%d\n",
  413.                 FH(&wa->file), (int)wa->offset, (int)wa->data.data_len,
  414.                 res.status, fa.size));
  415.     if(res.status == NFS_OK)
  416.         output_attr(&fa, &res.attrstat_u.attributes);
  417.     return &res;
  418. }
  419.  
  420. /* ------------------------------------------------------------------------- */
  421.  
  422. nfsstat *nfsproc_link_2(linkargs *la, struct svc_req *rqstp)
  423. {
  424. static nfsstat    res;
  425.  
  426.     set_ids(rqstp);
  427.     bzero(&res, sizeof(res));
  428.     res = nfs_errno(-fo_link(FH(&(la->from)), FH(&(la->to.dir)), la->to.name));
  429.     DPRINTF(("nfsproc_link_2(fh=%d, todir=%d, toname=%s)->%d\n",
  430.                     FH(&la->from), FH(&la->to.dir), la->to.name, res));
  431.     return &res;
  432. }
  433.  
  434. /* ------------------------------------------------------------------------- */
  435.  
  436. struct readlinkres *nfsproc_readlink_2(struct nfs_fh *fh, struct svc_req *rqstp)
  437. {
  438. static readlinkres    res;
  439. int                    rval;
  440.  
  441.     set_ids(rqstp);
  442.     bzero(&res, sizeof(res));
  443.     rval = fo_readlink(&res.readlinkres_u.data, FH(fh));
  444.     res.status = nfs_errno(rval < 0 ? -rval : 0);
  445.     DPRINTF(("nfsproc_readlink_2(fh=%d)->%d, path=%s\n",
  446.                             FH(fh), res.status, res.readlinkres_u.data));
  447.     return &res;
  448. }
  449.  
  450. /* ------------------------------------------------------------------------- */
  451.  
  452. nfsstat *nfsproc_symlink_2(symlinkargs *sa, struct svc_req *rqstp)
  453. {
  454. static nfsstat    res;
  455. my_attr_t        msa;
  456.  
  457.     set_ids(rqstp);
  458.     bzero(&res, sizeof(res));
  459.     input_attr(&msa, &sa->attributes);
  460.     res = nfs_errno(-fo_symlink(FH(&sa->from.dir), sa->from.name,
  461.                                                             sa->to, &msa));
  462.     DPRINTF(("nfsproc_symlink_2(dir=%d, name=%s, path=%s)->%d\n",
  463.                             FH(&sa->from.dir), sa->from.name, sa->to, res));
  464.     return &res;
  465. }
  466.  
  467. /* ------------------------------------------------------------------------- */
  468.  
  469. /* Dummy routines */
  470. void *nfsproc_writecache_2()
  471. {
  472. static char res;
  473.  
  474.     eprintf("** nfsproc_writecache_2()\n");
  475.     res = NFSERR_FBIG;
  476.     return &res;
  477. }
  478.  
  479. /* ------------------------------------------------------------------------- */
  480.  
  481. void *nfsproc_null_2()
  482. {
  483. static char res;
  484.  
  485.     eprintf("** nfsproc_null_2()\n");
  486.     res = NFSERR_FBIG;
  487.     return &res;
  488. }
  489.  
  490. /* ------------------------------------------------------------------------- */
  491.  
  492. void *nfsproc_root_2()
  493. {
  494. static char res;
  495.  
  496.     eprintf("** nfsproc_root_2()\n");
  497.     res = NFSERR_FBIG;
  498.     return &res;
  499. }
  500.  
  501. /* ------------------------------------------------------------------------- */
  502.