home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / comm / amitcp-sdk-4.0.lha / AmiTCP-SDK / src / rpclib / rpc_prot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-30  |  6.1 KB  |  265 lines

  1. /*
  2.  *      $Id: rpc_prot.c,v 4.2 1994/09/29 23:48:50 jraja Exp $
  3.  *
  4.  *      Routines to implement the RPC message protocol.
  5.  *      
  6.  *      Copyright © 1994 AmiTCP/IP Group,
  7.  *                       Network Solutions Development Inc.
  8.  *                       All rights reserved. 
  9.  */
  10.  
  11. /* @(#)rpc_prot.c    2.3 88/08/07 4.0 RPCSRC */
  12. #if !defined(lint) && defined(SCCSIDS)
  13. static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
  14. #endif
  15.  
  16. /*
  17.  * Copyright (C) 1984, Sun Microsystems, Inc.
  18.  *
  19.  * This set of routines implements the rpc message definition,
  20.  * its serializer and some common rpc utility routines.
  21.  * The routines are meant for various implementations of rpc -
  22.  * they are NOT for the rpc client or rpc service implementations!
  23.  * Because authentication stuff is easy and is part of rpc, the opaque
  24.  * routines are also in this program.
  25.  */
  26.  
  27. #include <sys/param.h>
  28. #include <rpc/rpc.h>
  29.  
  30. /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  31.  
  32. /* struct opaque_auth _null_auth; This is defined in the rpc_commondata.c*/
  33.  
  34. /*
  35.  * XDR an opaque authentication struct
  36.  * (see auth.h)
  37.  */
  38. bool_t XDRFUN
  39. xdr_opaque_auth(xdrs, ap)
  40.     register XDR *xdrs;
  41.     register struct opaque_auth *ap;
  42. {
  43.  
  44.     if (xdr_enum(xdrs, &(ap->oa_flavor)))
  45.         return (xdr_bytes(xdrs, &ap->oa_base,
  46.             &ap->oa_length, MAX_AUTH_BYTES));
  47.     return (FALSE);
  48. }
  49.  
  50. /*
  51.  * XDR a DES block
  52.  */
  53. bool_t XDRFUN
  54. xdr_des_block(xdrs, blkp)
  55.     register XDR *xdrs;
  56.     register des_block *blkp;
  57. {
  58.     return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
  59. }
  60.  
  61. /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  62.  
  63. /*
  64.  * XDR the MSG_ACCEPTED part of a reply message union
  65.  */
  66. bool_t  XDRFUN
  67. xdr_accepted_reply(xdrs, ar)
  68.     register XDR *xdrs;   
  69.     register struct accepted_reply *ar;
  70. {
  71.  
  72.     /* personalized union, rather than calling xdr_union */
  73.     if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  74.         return (FALSE);
  75.     if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  76.         return (FALSE);
  77.     switch (ar->ar_stat) {
  78.  
  79.     case SUCCESS:
  80.         return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  81.  
  82.     case PROG_MISMATCH:
  83.         if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  84.             return (FALSE);
  85.         return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  86.     }
  87.     return (TRUE);  /* TRUE => open ended set of problems */
  88. }
  89.  
  90. /*
  91.  * XDR the MSG_DENIED part of a reply message union
  92.  */
  93. bool_t  XDRFUN
  94. xdr_rejected_reply(xdrs, rr)
  95.     register XDR *xdrs;
  96.     register struct rejected_reply *rr;
  97. {
  98.  
  99.     /* personalized union, rather than calling xdr_union */
  100.     if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  101.         return (FALSE);
  102.     switch (rr->rj_stat) {
  103.  
  104.     case RPC_MISMATCH:
  105.         if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  106.             return (FALSE);
  107.         return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  108.  
  109.     case AUTH_ERROR:
  110.         return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  111.     }
  112.     return (FALSE);
  113. }
  114.  
  115. static struct xdr_discrim reply_dscrm[3] = {
  116.     { (int)MSG_ACCEPTED, xdr_accepted_reply },
  117.     { (int)MSG_DENIED, xdr_rejected_reply },
  118.     { __dontcare__, NULL_xdrproc_t } };
  119.  
  120. /*
  121.  * XDR a reply message
  122.  */
  123. bool_t XDRFUN
  124. xdr_replymsg(xdrs, rmsg)
  125.     register XDR *xdrs;
  126.     register struct rpc_msg *rmsg;
  127. {
  128.     if (
  129.         xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  130.         xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  131.         (rmsg->rm_direction == REPLY) )
  132.         return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  133.            (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  134.     return (FALSE);
  135. }
  136.  
  137.  
  138. /*
  139.  * Serializes the "static part" of a call message header.
  140.  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  141.  * The rm_xid is not really static, but the user can easily munge on the fly.
  142.  */
  143. bool_t XDRFUN
  144. xdr_callhdr(xdrs, cmsg)
  145.     register XDR *xdrs;
  146.     register struct rpc_msg *cmsg;
  147. {
  148.  
  149.     cmsg->rm_direction = CALL;
  150.     cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  151.     if (
  152.         (xdrs->x_op == XDR_ENCODE) &&
  153.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  154.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  155.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  156.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  157.         return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  158.     return (FALSE);
  159. }
  160.  
  161. /* ************************** Client utility routine ************* */
  162.  
  163. static void
  164. accepted(enum accept_stat acpt_stat, struct rpc_err * error)
  165. {
  166.  
  167.     switch (acpt_stat) {
  168.  
  169.     case PROG_UNAVAIL:
  170.         error->re_status = RPC_PROGUNAVAIL;
  171.         return;
  172.  
  173.     case PROG_MISMATCH:
  174.         error->re_status = RPC_PROGVERSMISMATCH;
  175.         return;
  176.  
  177.     case PROC_UNAVAIL:
  178.         error->re_status = RPC_PROCUNAVAIL;
  179.         return;
  180.  
  181.     case GARBAGE_ARGS:
  182.         error->re_status = RPC_CANTDECODEARGS;
  183.         return;
  184.  
  185.     case SYSTEM_ERR:
  186.         error->re_status = RPC_SYSTEMERROR;
  187.         return;
  188.  
  189.     case SUCCESS:
  190.         error->re_status = RPC_SUCCESS;
  191.         return;
  192.     }
  193.     /* something's wrong, but we don't know what ... */
  194.     error->re_status = RPC_FAILED;
  195.     error->re_lb.s1 = (long)MSG_ACCEPTED;
  196.     error->re_lb.s2 = (long)acpt_stat;
  197. }
  198.  
  199. static void 
  200. rejected(enum reject_stat rjct_stat, struct rpc_err * error)
  201. {
  202.  
  203.     switch (rjct_stat) {
  204.  
  205.     case RPC_VERSMISMATCH:
  206.         error->re_status = RPC_VERSMISMATCH;
  207.         return;
  208.  
  209.     case AUTH_ERROR:
  210.         error->re_status = RPC_AUTHERROR;
  211.         return;
  212.     }
  213.     /* something's wrong, but we don't know what ... */
  214.     error->re_status = RPC_FAILED;
  215.     error->re_lb.s1 = (long)MSG_DENIED;
  216.     error->re_lb.s2 = (long)rjct_stat;
  217. }
  218.  
  219. /*
  220.  * given a reply message, fills in the error
  221.  */
  222. void
  223. _seterr_reply(msg, error)
  224.     register struct rpc_msg *msg;
  225.     register struct rpc_err *error;
  226. {
  227.  
  228.     /* optimized for normal, SUCCESSful case */
  229.     switch (msg->rm_reply.rp_stat) {
  230.  
  231.     case MSG_ACCEPTED:
  232.         if (msg->acpted_rply.ar_stat == SUCCESS) {
  233.             error->re_status = RPC_SUCCESS;
  234.             return;
  235.         };
  236.         accepted(msg->acpted_rply.ar_stat, error);
  237.         break;
  238.  
  239.     case MSG_DENIED:
  240.         rejected(msg->rjcted_rply.rj_stat, error);
  241.         break;
  242.  
  243.     default:
  244.         error->re_status = RPC_FAILED;
  245.         error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  246.         break;
  247.     }
  248.     switch (error->re_status) {
  249.  
  250.     case RPC_VERSMISMATCH:
  251.         error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  252.         error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  253.         break;
  254.  
  255.     case RPC_AUTHERROR:
  256.         error->re_why = msg->rjcted_rply.rj_why;
  257.         break;
  258.  
  259.     case RPC_PROGVERSMISMATCH:
  260.         error->re_vers.low = msg->acpted_rply.ar_vers.low;
  261.         error->re_vers.high = msg->acpted_rply.ar_vers.high;
  262.         break;
  263.     }
  264. }
  265.