1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2015 Gary Mills
  25  */
  26 
  27 /*
  28  * This is a non-recursive version of XDR routine used for db_index_entry
  29  * type.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/syslog.h>
  34 #include <stdio.h>
  35 #include <rpc/types.h>
  36 #include <rpc/xdr.h>
  37 #include <memory.h>
  38 #include "db_index_entry_c.h"
  39 #include "db_table_c.h"
  40 #include "xdr_nullptr.h"
  41 
  42 bool_t
  43 xdr_db_index_entry(xdrs, objp)
  44         register XDR *xdrs;
  45         db_index_entry *objp;
  46 {
  47         bool_t  more_data;
  48         register db_index_entry *ep = objp;
  49         register db_index_entry *loc;
  50         register db_index_entry *freeptr = NULL;
  51 
  52         for (;;) {
  53                 if (!xdr_u_long(xdrs, &ep->hashval))
  54                         return (FALSE);
  55                 if (!xdr_pointer(xdrs, (char **)&ep->key, sizeof (item),
  56                         (xdrproc_t) xdr_item))
  57                         return (FALSE);
  58                 if (!xdr_entryp(xdrs, &ep->location))
  59                         return (FALSE);
  60                 if (!xdr_nullptr(xdrs, &ep->next_result))
  61                         return (FALSE);
  62 
  63                 /*
  64                  * The following code replaces the call to
  65                  * xdr_pointer(
  66                  *      xdrs,
  67                  *      (char **)&ep->next,
  68                  *      sizeof (db_index_entry),
  69                  *      (xdrproc_t) xdr_db_index_entry))
  70                  *
  71                  * It's a modified version of xdr_refer.c from the rpc library:
  72                  *      @(#)xdr_refer.c         1.8     92/07/20 SMI
  73                  */
  74 
  75 
  76                 /*
  77                  * the following assignment to more_data is only useful when
  78                  * encoding and freeing.  When decoding, more_data will be
  79                  * filled by the xdr_bool() routine.
  80                  */
  81                 more_data = (ep->next != NULL);
  82                 if (! xdr_bool(xdrs, &more_data))
  83                         return (FALSE);
  84                 if (! more_data) {
  85                         ep->next = NULL;
  86                         break;
  87                 }
  88 
  89                 loc = ep->next;
  90 
  91 
  92                 switch (xdrs->x_op) {
  93                 case XDR_DECODE:
  94                         if (loc == NULL) {
  95                                 ep->next = loc = (db_index_entry *)
  96                                         mem_alloc(sizeof (db_index_entry));
  97                                 if (loc == NULL) {
  98                                         syslog(LOG_ERR,
  99                                 "xdr_db_index_entry: mem_alloc failed");
 100                                         return (FALSE);
 101                                 }
 102                                 memset(loc, 0, sizeof (db_index_entry));
 103                         }
 104                         break;
 105                 case XDR_FREE:
 106                         if (freeptr != NULL) {
 107                                 mem_free(freeptr, sizeof (db_index_entry));
 108                         } else
 109                                 ep->next = NULL;
 110                         freeptr = loc;
 111                         break;
 112                 }
 113 
 114                 if (loc == NULL)
 115                         break;
 116                 ep = loc;
 117         }       /* for loop */
 118 
 119         if ((freeptr != NULL) && (xdrs->x_op == XDR_FREE)) {
 120                 mem_free(freeptr, sizeof (db_index_entry));
 121         }
 122 
 123         return (TRUE);
 124 }
 125 
 126 
 127 bool_t
 128 xdr_db_index_entry_p(xdrs, objp)
 129         register XDR *xdrs;
 130         db_index_entry_p *objp;
 131 {
 132 
 133         if (!xdr_pointer(xdrs, (char **)objp, sizeof (db_index_entry),
 134                 (xdrproc_t) xdr_db_index_entry))
 135                 return (FALSE);
 136         return (TRUE);
 137 }
 138 
 139 
 140 
 141 bool_t
 142 xdr_db_free_entry(xdrs, objp)
 143         register XDR *xdrs;
 144         db_free_entry *objp;
 145 {
 146         bool_t  more_data;
 147         register db_free_entry *ep = objp;
 148         register db_free_entry *loc;
 149         register db_free_entry *freeptr = NULL;
 150 
 151         for (;;) {
 152                 if (!xdr_entryp(xdrs, &ep->where))
 153                         return (FALSE);
 154 
 155                 /*
 156                  * The following code replaces the call to
 157                  * xdr_pointer(
 158                  *      xdrs,
 159                  *      (char **)&ep->next,
 160                  *      sizeof (db_free_entry),
 161                  *      (xdrproc_t) xdr_db_free_entry))
 162                  *
 163                  * It's a modified version of xdr_refer.c from the rpc library:
 164                  *      @(#)xdr_refer.c         1.8     92/07/20 SMI
 165                  */
 166 
 167 
 168                 /*
 169                  * the following assignment to more_data is only useful when
 170                  * encoding and freeing.  When decoding, more_data will be
 171                  * filled by the xdr_bool() routine.
 172                  */
 173                 more_data = (ep->next != NULL);
 174                 if (! xdr_bool(xdrs, &more_data))
 175                         return (FALSE);
 176                 if (! more_data) {
 177                         ep->next = NULL;
 178                         break;
 179                 }
 180 
 181                 loc = ep->next;
 182 
 183 
 184                 switch (xdrs->x_op) {
 185                 case XDR_DECODE:
 186                         if (loc == NULL) {
 187                                 ep->next = loc = (db_free_entry *)
 188                                         mem_alloc(sizeof (db_free_entry));
 189                                 if (loc == NULL) {
 190                                         syslog(LOG_ERR,
 191                                 "db_free_entry: mem_alloc failed");
 192                                         return (FALSE);
 193                                 }
 194                                 memset(loc, 0, sizeof (db_free_entry));
 195                         }
 196                         break;
 197                 case XDR_FREE:
 198                         if (freeptr != NULL) {
 199                                 mem_free(freeptr, sizeof (db_free_entry));
 200                         } else
 201                                 ep->next = NULL;
 202                         freeptr = loc;
 203                         break;
 204                 }
 205 
 206                 if (loc == NULL)
 207                         break;
 208                 ep = loc;
 209         }       /* for loop */
 210 
 211         if ((freeptr != NULL) && (xdrs->x_op == XDR_FREE)) {
 212                 mem_free(freeptr, sizeof (db_free_entry));
 213         }
 214         return (TRUE);
 215 }