home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / rpc3.9 / part03 / rpc_prot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-27  |  6.9 KB  |  279 lines

  1. /* @(#)rpc_prot.c    1.2 87/11/23 3.9 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #if !defined(lint) && defined(SCCSIDS)
  31. static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
  32. #endif
  33.  
  34. /*
  35.  * rpc_prot.c
  36.  *
  37.  * Copyright (C) 1984, Sun Microsystems, Inc.
  38.  *
  39.  * This set of routines implements the rpc message definition,
  40.  * its serializer and some common rpc utility routines.
  41.  * The routines are meant for various implementations of rpc -
  42.  * they are NOT for the rpc client or rpc service implementations!
  43.  * Because authentication stuff is easy and is part of rpc, the opaque
  44.  * routines are also in this program.
  45.  */
  46.  
  47. #include <sys/param.h>
  48.  
  49. #include <rpc/rpc.h>
  50.  
  51. /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  52.  
  53. struct opaque_auth _null_auth;
  54.  
  55. /*
  56.  * XDR an opaque authentication struct
  57.  * (see auth.h)
  58.  */
  59. bool_t
  60. xdr_opaque_auth(xdrs, ap)
  61.     register XDR *xdrs;
  62.     register struct opaque_auth *ap;
  63. {
  64.  
  65.     if (xdr_enum(xdrs, &(ap->oa_flavor)))
  66.         return (xdr_bytes(xdrs, &ap->oa_base,
  67.             &ap->oa_length, MAX_AUTH_BYTES));
  68.     return (FALSE);
  69. }
  70.  
  71. /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  72.  
  73. /*
  74.  * XDR the MSG_ACCEPTED part of a reply message union
  75.  */
  76. bool_t 
  77. xdr_accepted_reply(xdrs, ar)
  78.     register XDR *xdrs;   
  79.     register struct accepted_reply *ar;
  80. {
  81.  
  82.     /* personalized union, rather than calling xdr_union */
  83.     if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  84.         return (FALSE);
  85.     if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  86.         return (FALSE);
  87.     switch (ar->ar_stat) {
  88.  
  89.     case SUCCESS:
  90.         return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  91.     
  92.     case PROG_MISMATCH:
  93.         if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  94.             return (FALSE);
  95.         return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  96.     }
  97.     return (TRUE);  /* TRUE => open ended set of problems */
  98. }
  99.  
  100. /*
  101.  * XDR the MSG_DENIED part of a reply message union
  102.  */
  103. bool_t 
  104. xdr_rejected_reply(xdrs, rr)
  105.     register XDR *xdrs;
  106.     register struct rejected_reply *rr;
  107. {
  108.  
  109.     /* personalized union, rather than calling xdr_union */
  110.     if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  111.         return (FALSE);
  112.     switch (rr->rj_stat) {
  113.  
  114.     case RPC_MISMATCH:
  115.         if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  116.             return (FALSE);
  117.         return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  118.  
  119.     case AUTH_ERROR:
  120.         return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  121.     }
  122.     return (FALSE);
  123. }
  124.  
  125. static struct xdr_discrim reply_dscrm[3] = {
  126.     { (int)MSG_ACCEPTED, xdr_accepted_reply },
  127.     { (int)MSG_DENIED, xdr_rejected_reply },
  128.     { __dontcare__, NULL_xdrproc_t } };
  129.  
  130. /*
  131.  * XDR a reply message
  132.  */
  133. bool_t
  134. xdr_replymsg(xdrs, rmsg)
  135.     register XDR *xdrs;
  136.     register struct rpc_msg *rmsg;
  137. {
  138.     if (
  139.         xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  140.         xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  141.         (rmsg->rm_direction == REPLY) )
  142.         return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  143.            (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  144.     return (FALSE);
  145. }
  146.  
  147.  
  148. /*
  149.  * Serializes the "static part" of a call message header.
  150.  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  151.  * The rm_xid is not really static, but the user can easily munge on the fly.
  152.  */
  153. bool_t
  154. xdr_callhdr(xdrs, cmsg)
  155.     register XDR *xdrs;
  156.     register struct rpc_msg *cmsg;
  157. {
  158.  
  159.     cmsg->rm_direction = CALL;
  160.     cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  161.     if (
  162.         (xdrs->x_op == XDR_ENCODE) &&
  163.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  164.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  165.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  166.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  167.         return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  168.     return (FALSE);
  169. }
  170.  
  171. /* ************************** Client utility routine ************* */
  172.  
  173. static void
  174. accepted(acpt_stat, error)
  175.     register enum accept_stat acpt_stat;
  176.     register struct rpc_err *error;
  177. {
  178.  
  179.     switch (acpt_stat) {
  180.  
  181.     case PROG_UNAVAIL:
  182.         error->re_status = RPC_PROGUNAVAIL;
  183.         return;
  184.  
  185.     case PROG_MISMATCH:
  186.         error->re_status = RPC_PROGVERSMISMATCH;
  187.         return;
  188.  
  189.     case PROC_UNAVAIL:
  190.         error->re_status = RPC_PROCUNAVAIL;
  191.         return;
  192.  
  193.     case GARBAGE_ARGS:
  194.         error->re_status = RPC_CANTDECODEARGS;
  195.         return;
  196.  
  197.     case SYSTEM_ERR:
  198.         error->re_status = RPC_SYSTEMERROR;
  199.         return;
  200.  
  201.     case SUCCESS:
  202.         error->re_status = RPC_SUCCESS;
  203.         return;
  204.     }
  205.     /* something's wrong, but we don't know what ... */
  206.     error->re_status = RPC_FAILED;
  207.     error->re_lb.s1 = (long)MSG_ACCEPTED;
  208.     error->re_lb.s2 = (long)acpt_stat;
  209. }
  210.  
  211. static void 
  212. rejected(rjct_stat, error)
  213.     register enum reject_stat rjct_stat;
  214.     register struct rpc_err *error;
  215. {
  216.  
  217.     switch (rjct_stat) {
  218.  
  219.     case RPC_VERSMISMATCH:
  220.         error->re_status = RPC_VERSMISMATCH;
  221.         return;
  222.  
  223.     case AUTH_ERROR:
  224.         error->re_status = RPC_AUTHERROR;
  225.         return;
  226.     }
  227.     /* something's wrong, but we don't know what ... */
  228.     error->re_status = RPC_FAILED;
  229.     error->re_lb.s1 = (long)MSG_DENIED;
  230.     error->re_lb.s2 = (long)rjct_stat;
  231. }
  232.  
  233. /*
  234.  * given a reply message, fills in the error
  235.  */
  236. void
  237. _seterr_reply(msg, error)
  238.     register struct rpc_msg *msg;
  239.     register struct rpc_err *error;
  240. {
  241.  
  242.     /* optimized for normal, SUCCESSful case */
  243.     switch (msg->rm_reply.rp_stat) {
  244.  
  245.     case MSG_ACCEPTED:
  246.         if (msg->acpted_rply.ar_stat == SUCCESS) {
  247.             error->re_status = RPC_SUCCESS;
  248.             return;
  249.         };
  250.         accepted(msg->acpted_rply.ar_stat, error);
  251.         break;
  252.  
  253.     case MSG_DENIED:
  254.         rejected(msg->rjcted_rply.rj_stat, error);
  255.         break;
  256.  
  257.     default:
  258.         error->re_status = RPC_FAILED;
  259.         error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  260.         break;
  261.     }
  262.     switch (error->re_status) {
  263.  
  264.     case RPC_VERSMISMATCH:
  265.         error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  266.         error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  267.         break;
  268.  
  269.     case RPC_AUTHERROR:
  270.         error->re_why = msg->rjcted_rply.rj_why;
  271.         break;
  272.  
  273.     case RPC_PROGVERSMISMATCH:
  274.         error->re_vers.low = msg->acpted_rply.ar_vers.low;
  275.         error->re_vers.high = msg->acpted_rply.ar_vers.high;
  276.         break;
  277.     }
  278. }
  279.