home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / nfsd / src / nfs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-30  |  7.0 KB  |  248 lines

  1. /*  RPC handling code for the NFS protocol
  2.  
  3.     ©1999 Joseph Walton
  4.  
  5.     This software is distributed under the terms of the GNU General Public
  6.     License; either version 2 of the License, or (at your option) any
  7.     later version.
  8. */
  9.  
  10. /*
  11.     This would probably benefit from having most functions made inline.
  12. */
  13.  
  14. #include "nfs.h"
  15. #include "rpc.h"
  16. #include "nfsd.h"
  17.  
  18. #include "nfs_functions.h"
  19.  
  20. #include <stdio.h>
  21.  
  22. int32 *readHandle(int32 *ptr, int32 *limit, nfs_fh **hp);
  23. int32 *readSattr(int32 *ptr, int32 *limit, struct sattr *sa);
  24. int32 *readDirOpArgs(int32 *ptr, int32 *limit, struct diropargs *doa);
  25.  
  26. int nfs_procedure(struct Call *call, int32 *ptr, int32 *limit,
  27.     int32 *rptr, int32 *rlimit)
  28. {
  29.     if (call->c_version != NFS_VERSION) {
  30.         *rptr++ = P_ENUM(PROG_MISMATCH);
  31.         *rptr++ = P_UINT(NFS_VERSION);
  32.         *rptr = P_UINT(NFS_VERSION);
  33.         return 8;
  34.     }
  35.  
  36.     switch (call->c_procedure) {
  37.         case NFS_PROC_NULL:
  38.             *rptr = P_ENUM(SUCCESS);
  39.             return 6;
  40.  
  41.         case NFS_PROC_GETATTR:
  42.             nfs_fh *handle;
  43.  
  44.             if (readHandle(ptr, limit, &handle)) {
  45.                 *rptr++ = P_ENUM(SUCCESS);
  46.                 return nfsproc_getattr_2_svc(handle, call, rptr);
  47.             }
  48.             break;
  49.  
  50.         case NFS_PROC_SETATTR:
  51.             struct sattrargs args;
  52.             ptr = readHandle(ptr, limit, &args.handle);
  53.             ptr = readSattr(ptr, limit, &args.sattr);
  54.             if (ptr) {
  55.                 *rptr++ = P_ENUM(SUCCESS);
  56.                 return nfsproc_setattr_2_svc(&args, call, rptr);
  57.             }
  58.             break;
  59.  
  60.         case NFS_PROC_LOOKUP:
  61.             struct diropargs args;
  62.             if (readDirOpArgs(ptr, limit, &args)) {
  63.                 *rptr++ = P_ENUM(SUCCESS);
  64.                 return nfsproc_lookup_2_svc(&args, call, rptr);
  65.             }
  66.             break;
  67.  
  68.         case NFS_PROC_CREATE:
  69.             struct createargs args;
  70.             ptr = readDirOpArgs(ptr, limit, &args.where);
  71.             ptr = readSattr(ptr, limit, &args.sattr);
  72.             if (ptr) {
  73.                 *rptr++ = P_ENUM(SUCCESS);
  74.                 return nfsproc_create_2_svc(&args, call, rptr);
  75.             }
  76.             break;
  77.  
  78.         case NFS_PROC_REMOVE:
  79.             struct diropargs args;
  80.             if (readDirOpArgs(ptr, limit, &args)) {
  81.                 *rptr++ = P_ENUM(SUCCESS);
  82.                 *rptr = P_ENUM(nfsproc_remove_2_svc(&args, call));
  83.                 return 7;
  84.             }
  85.             break;
  86.  
  87.         case NFS_PROC_RENAME:
  88.             struct renameargs args;
  89.  
  90.             ptr = readDirOpArgs(ptr, limit, &args.from);
  91.             if (readDirOpArgs(ptr, limit, &args.to)) {
  92.                 *rptr++ = P_ENUM(SUCCESS);
  93.                 *rptr = P_ENUM(nfsproc_rename_2_svc(&args, call));
  94.                 return 7;
  95.             }
  96.             break;
  97.  
  98.         case NFS_PROC_MKDIR:
  99.             struct createargs args;
  100.             ptr = readDirOpArgs(ptr, limit, &args.where);
  101.             if (readSattr(ptr, limit, &args.sattr)) {
  102.                 *rptr++ = P_ENUM(SUCCESS);
  103.                 return nfsproc_mkdir_2_svc(&args, call, rptr);
  104.             }
  105.             break;
  106.  
  107.         case NFS_PROC_RMDIR:
  108.             struct diropargs args;
  109.             if (readDirOpArgs(ptr, limit, &args)) {
  110.                 *rptr++ = P_ENUM(SUCCESS);
  111.                 *rptr = P_ENUM(nfsproc_rmdir_2_svc(&args, call));
  112.                 return 7;
  113.             }
  114.             break;
  115.  
  116.         case NFS_PROC_STATFS:
  117.             nfs_fh *handle;
  118.  
  119.             if (readHandle(ptr, limit, &handle)) {
  120.                 *rptr++ = P_ENUM(SUCCESS);
  121.                 return nfsproc_statfs_2_svc(handle, call, rptr);
  122.             }
  123.             break;
  124.  
  125.         case NFS_PROC_READ:
  126.             struct readargs args;
  127.  
  128.             if ((limit - ptr) >= (INT32S(NFS_FHSIZE) + 3)) {
  129.                 args.handle = ptr;
  130.                 ptr += INT32S(NFS_FHSIZE);
  131.                 args.offset = G_UINT(*ptr++);
  132.                 args.count = G_UINT(*ptr++);
  133.                 /* Ignore totalcount */
  134.                 *rptr++ = P_ENUM(SUCCESS);
  135.                 return nfsproc_read_2_svc(&args, call, rptr, rlimit);
  136.             }
  137.             break;
  138.  
  139.         case NFS_PROC_WRITE:
  140.             struct writeargs args;
  141.  
  142.             if ((limit - ptr) >= (INT32S(NFS_FHSIZE) + 4)) {
  143.                 args.handle = ptr;
  144.                 ptr += INT32S(NFS_FHSIZE);
  145.                 ptr++; /* Ignore beginoffset */
  146.                 args.offset = G_UINT(*ptr++);
  147.                 ptr++; /* Ignore totalcount */
  148.  
  149.                 args.count = G_UINT(*ptr++);
  150.  
  151.                 if (INT32S(args.count) <= (limit - ptr)) {
  152.                     args.data = (BYTE *)ptr;
  153.                      *rptr++ = P_ENUM(SUCCESS);
  154.                     return nfsproc_write_2_svc(&args, call, rptr);
  155.                 }
  156.             }
  157.             break;
  158.  
  159.         case NFS_PROC_READDIR:
  160.             struct readdirargs args;
  161.  
  162.             if ((limit - ptr) >= (INT32S(NFS_FHSIZE) + 2)) {
  163.                 args.dir_handle = ptr;
  164.                 ptr += INT32S(NFS_FHSIZE);
  165.  
  166.                 args.cookie = G_UINT(*ptr++);
  167.                 args.count = G_UINT(*ptr);
  168.  
  169.                 *rptr++ = P_ENUM(SUCCESS);
  170.                 return nfsproc_readdir(&args, call, rptr, rlimit);
  171.             }
  172.             break;
  173.  
  174.         /* Links are not supported currently, as they could potentially
  175.             be used to subvert security */
  176.         case NFS_PROC_READLINK:
  177.         case NFS_PROC_LINK:
  178.         case NFS_PROC_SYMLINK:
  179.             *rptr++ = P_ENUM(SUCCESS);
  180.             *rptr   = P_ENUM(NFSERR_ACCES);
  181.             return 7;
  182.  
  183.         case NFS_PROC_ROOT:  // This isn't part of the protocol any more
  184.         case NFS_PROC_WRITECACHE: // And this one's not in V2 proper
  185.         default:
  186.             *rptr = P_ENUM(PROC_UNAVAIL);
  187.             return 6;
  188.     }
  189.  
  190.     /* We fell through */
  191.     *rptr = P_ENUM(GARBAGE_ARGS);
  192.     return 6;
  193. }
  194.  
  195. static int32 *readHandle(int32 *ptr, int32 *limit, nfs_fh **hp)
  196. {
  197.     if (!ptr)
  198.         return NULL;
  199.  
  200.     *hp = ptr;
  201.     ptr += INT32S(NFS_FHSIZE);
  202.     if (ptr <= limit) { /* <=, as this may be the last thing in the packet */
  203.         return ptr;
  204.     }
  205.     return NULL;
  206. }
  207.  
  208. static int32 *readSattr(int32 *ptr, int32 *limit, struct sattr *sa)
  209. {
  210.     /* Check there's enough space */
  211.     if (!ptr || ((limit - ptr) < 8)) {
  212.         return NULL;
  213.     }
  214.  
  215.     /* This is exactly equivalent to CopyMem(), except in the case
  216.         where this is a little-endian Amiga. Which could happen. */
  217.     sa->mode = G_UINT(*ptr++);
  218.     sa->uid = G_UINT(*ptr++);
  219.     sa->gid = G_UINT(*ptr++);
  220.     sa->size = G_UINT(*ptr++);
  221.     sa->atime.seconds = G_UINT(*ptr++);
  222.     sa->atime.useconds = G_UINT(*ptr++);
  223.     sa->mtime.seconds = G_UINT(*ptr++);
  224.     sa->mtime.useconds = G_UINT(*ptr++);
  225.  
  226.     return ptr;
  227. }
  228.  
  229. static int32 *readDirOpArgs(int32 *ptr, int32 *limit, struct diropargs *doa)
  230. {
  231.     if (!ptr) {
  232.         return NULL;
  233.     }
  234.  
  235.     if (ptr >= limit) {
  236.         return NULL;
  237.     }
  238.  
  239.     doa->dir_handle = ptr;
  240.     ptr += INT32S(NFS_FHSIZE);
  241.  
  242.     if (ptr < limit) {
  243.         return getString(ptr, limit, doa->filename, NFS_MAXNAMELEN + 1);
  244.     }
  245.     return NULL;
  246. }
  247.  
  248.