libafscp: code cleanup
[openafs.git] / src / libafscp / afscp_callback.c
index f001b3c..dfb5b3b 100644 (file)
@@ -24,433 +24,704 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
+#include <afsconfig.h>
 #include <afs/param.h>
-#include <afs/afsint.h>               /*Callback interface defs*/
+
+#include <roken.h>
+
 #include <afs/afsutil.h>
-#include <stdlib.h>
-#include <string.h>
+#ifdef AFS_NT40_ENV
+#include <windows.h>
+#include <rpc.h>
+#endif
 #include "afscp.h"
 #include "afscp_internal.h"
 
 int afs_cb_inited = 0;
 struct interfaceAddr afs_cb_interface;
-static int afs_maxcallbacks=0, afs_cballoced=0;
-struct afs_callback *allcallbacks=NULL;
-
-static int init_afs_cb() {
-    int count;
-
+static int afscp_maxcallbacks = 0, afscp_cballoced = 0;
+struct afscp_callback *allcallbacks = NULL;
+
+/*!
+ * Initialize the callback interface structure
+ */
+static int
+init_afs_cb(void)
+{
+    int cm_noIPAddr;           /* number of client network interfaces */
+#ifdef AFS_NT40_ENV
+    /*
+     * This Windows section was pulled in from changes to src/venus/afsio.c but is
+     * untested here and may be unnecessary if rx_getAllAddr() can be used on that
+     * platform.  However, there was already an ifdef here surrounding UuidCreate().
+     */
+    int code;
+    int cm_IPAddr[CM_MAXINTERFACE_ADDR];       /* client's IP address in host order */
+    int cm_SubnetMask[CM_MAXINTERFACE_ADDR];   /* client's subnet mask in host order */
+    int cm_NetMtu[CM_MAXINTERFACE_ADDR];       /* client's MTU sizes */
+    int cm_NetFlags[CM_MAXINTERFACE_ADDR];     /* network flags */
+    int i;
+
+    UuidCreate((UUID *) & afs_cb_interface.uuid);
+    cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+    code = syscfg_GetIFInfo(&cm_noIPAddr,
+                           cm_IPAddr, cm_SubnetMask, cm_NetMtu, cm_NetFlags);
+    if (code > 0) {
+       /* return all network interface addresses */
+       afs_cb_interface.numberOfInterfaces = cm_noIPAddr;
+       for (i = 0; i < cm_noIPAddr; i++) {
+           afs_cb_interface.addr_in[i] = cm_IPAddr[i];
+           afs_cb_interface.subnetmask[i] = cm_SubnetMask[i];
+           afs_cb_interface.mtu[i] = (rx_mtu == -1
+                                      || (rx_mtu != -1
+                                          && cm_NetMtu[i] <
+                                          rx_mtu)) ? cm_NetMtu[i] : rx_mtu;
+       }
+    } else {
+       afs_cb_interface.numberOfInterfaces = 0;
+    }
+#else
     afs_uuid_create(&afs_cb_interface.uuid);
-    count = rx_getAllAddr(&afs_cb_interface.addr_in, AFS_MAX_INTERFACE_ADDR);
-    if ( count <= 0 )
-        afs_cb_interface.numberOfInterfaces = 0;
+    cm_noIPAddr =
+       rx_getAllAddr((afs_uint32 *) afs_cb_interface.addr_in,
+                     AFS_MAX_INTERFACE_ADDR);
+    if (cm_noIPAddr < 0)
+       afs_cb_interface.numberOfInterfaces = 0;
     else
-        afs_cb_interface.numberOfInterfaces = count;
+       afs_cb_interface.numberOfInterfaces = cm_noIPAddr;
+#endif
     afs_cb_inited = 1;
     return 0;
-}
+}                              /* init_afs_cb */
 
-int AddCallBack(const struct afs_server *server, const struct AFSFid *fid,
-                const struct AFSFetchStatus *fst, const struct AFSCallBack *cb)
+int
+afscp_AddCallBack(const struct afscp_server *server,
+                 const struct AFSFid *fid,
+                 const struct AFSFetchStatus *fst,
+                 const struct AFSCallBack *cb, const time_t as_of)
 {
-     int i;
-     struct afs_callback *use=NULL, *newlist;
-     struct afs_venusfid f;
-     time_t now;
-
-     time(&now);
-
-     for (i=0;i<afs_maxcallbacks;i++) {
-         if (allcallbacks[i].cb.ExpirationTime < now) {
-            if (allcallbacks[i].valid) {
-                 f.cell=afs_cellbyid(allcallbacks[i].server->cell);
-                 memcpy(&f.fid, &allcallbacks[i].fid, sizeof(struct afs_venusfid));
-                 _StatInvalidate(&f);
-            }
-           allcallbacks[i].valid=0;
-
-         }
-
-          if (allcallbacks[i].valid == 0)
-               use=&allcallbacks[i];
-         if (allcallbacks[i].server==server &&
-             fid->Volume == allcallbacks[i].fid.Volume &&
-             fid->Vnode == allcallbacks[i].fid.Vnode &&
-             fid->Unique == allcallbacks[i].fid.Unique) {
-           use=&allcallbacks[i];
+    int i;
+    struct afscp_callback *use = NULL, *newlist;
+    struct afscp_venusfid f;
+    time_t now;
+
+    time(&now);
+
+    for (i = 0; i < afscp_maxcallbacks; i++) {
+       if (allcallbacks[i].cb.ExpirationTime + allcallbacks[i].as_of < now) {
+           if (allcallbacks[i].valid) {
+               f.cell = afscp_CellById(allcallbacks[i].server->cell);
+               memcpy(&f.fid, &allcallbacks[i].fid, sizeof(struct AFSFid));
+               _StatInvalidate(&f);
+           }
+           allcallbacks[i].valid = 0;
+
+       }
+
+       if (allcallbacks[i].valid == 0)
+           use = &allcallbacks[i];
+       if ((allcallbacks[i].server == server) &&
+           (fid->Volume == allcallbacks[i].fid.Volume) &&
+           (fid->Vnode == allcallbacks[i].fid.Vnode) &&
+           (fid->Unique == allcallbacks[i].fid.Unique)) {
+           use = &allcallbacks[i];
            break;
-         }
-     }
-     if (!use) {
-          if (afs_maxcallbacks >= afs_cballoced) {
-               if (afs_cballoced)
-                    afs_cballoced = afs_cballoced *2;
-               else
-                    afs_cballoced = 4;
-               newlist=realloc(allcallbacks, afs_cballoced *
-                               sizeof(struct afs_callback));
-               if (!newlist)
-                    return -1;
-               allcallbacks=newlist;
-          }
-          use=&allcallbacks[afs_maxcallbacks++];
-     }
-     use->valid=1;
-     use->server=server;
-     memmove(&use->fid, fid, sizeof(struct AFSFid));
-     memmove(&use->cb, cb, sizeof(struct AFSCallBack));
-     f.cell=afs_cellbyid(server->cell);
-     memcpy(&f.fid, fid, sizeof(struct AFSFid));
-     _StatStuff(&f, fst);
-     return 0;
-}
-int RemoveCallBack(const struct afs_server *server, const struct afs_venusfid *f)
+       }
+    }
+    if (use == NULL) {
+       if (afscp_maxcallbacks >= afscp_cballoced) {
+           if (afscp_cballoced != 0)
+               afscp_cballoced = afscp_cballoced * 2;
+           else
+               afscp_cballoced = 4;
+           newlist = realloc(allcallbacks, afscp_cballoced *
+                             sizeof(struct afscp_callback));
+           if (newlist == NULL) {
+               return -1;
+           }
+           allcallbacks = newlist;
+       }
+       use = &allcallbacks[afscp_maxcallbacks++];
+    }
+    use->valid = 1;
+    use->server = server;
+    memmove(&use->fid, fid, sizeof(struct AFSFid));
+    memmove(&use->cb, cb, sizeof(struct AFSCallBack));
+    use->as_of = as_of;
+    f.cell = afscp_CellById(server->cell);
+    memcpy(&f.fid, fid, sizeof(struct AFSFid));
+    _StatStuff(&f, fst);
+    return 0;
+}                              /* afscp_AddCallBack */
+
+int
+afscp_RemoveCallBack(const struct afscp_server *server,
+                    const struct afscp_venusfid *f)
 {
-     struct afs_callback *cb;
-     int i;
-
-     _StatInvalidate(f);
-     if (!server)
-          return 0;
-     for (i=0;i<afs_maxcallbacks;i++) {
-          cb=&allcallbacks[i];
-          if (cb->server == server &&
-              f->fid.Volume == cb->fid.Volume &&
-              f->fid.Vnode == cb->fid.Vnode &&
-              f->fid.Unique == cb->fid.Unique) {
-               cb->valid = 0;
-               break;
-          }
-     }
-     return 0;
-}
-
-int ReturnCallBacks(const struct afs_server *server)
+    struct afscp_callback *cb;
+    int i;
+
+    _StatInvalidate(f);
+    if (server == NULL) {
+       return 0;
+    }
+    for (i = 0; i < afscp_maxcallbacks; i++) {
+       cb = &allcallbacks[i];
+       if ((cb->server == server) &&
+           (f->fid.Volume == cb->fid.Volume) &&
+           (f->fid.Vnode == cb->fid.Vnode) &&
+           (f->fid.Unique == cb->fid.Unique)) {
+           cb->valid = 0;
+           break;
+       }
+    }
+    return 0;
+}                              /* afscp_ReturnCallBacks */
+
+int
+afscp_ReturnCallBacks(const struct afscp_server *server)
 {
-     struct AFSCBFids theFids;
-     struct AFSCBs theCBs;
-     struct afs_callback *cb;
-     struct afs_venusfid f;
-     int inited=0;
-     int ncallbacks=0;
-     int i,j;
-     time_t now;
-
-     time(&now);
-
-     for (i=0;i<afs_maxcallbacks;i++) {
-          cb=&allcallbacks[i];
-/*          printf("%d %x %x %ld %d", i, cb, cb->server, cb->cb.ExpirationTime,
-            cb->valid);*/
-          if (cb->server != server)
-               continue;
-         if (cb->cb.ExpirationTime < now) {
-            if (cb->valid) {
-                 f.cell=afs_cellbyid(cb->server->cell);
-                 memcpy(&f.fid, &cb->fid, sizeof(struct afs_venusfid));
-                 _StatInvalidate(&f);
-            }
-
-           cb->valid=0;
+    struct AFSCBFids theFids;
+    struct AFSCBs theCBs;
+    struct afscp_callback *cb;
+    struct afscp_venusfid f;
+    struct rx_connection *c;
+    int inited = 0;
+    int ncallbacks = 0;
+    int i, j, code;
+    time_t now;
+
+    time(&now);
+
+    for (i = 0; i < afscp_maxcallbacks; i++) {
+       cb = &allcallbacks[i];
+       if (cb->server != server) {
            continue;
-         }
-          if (!inited) {
-               theFids.AFSCBFids_val=malloc(sizeof(struct AFSCallBack) * AFSCBMAX);
-               if (!theFids.AFSCBFids_val)
-                    return -1;
-               theCBs.AFSCBs_val=malloc(sizeof(struct AFSFid) * AFSCBMAX);
-               if (!theCBs.AFSCBs_val) {
-                    free(theFids.AFSCBFids_val);
-                    return -1;
-               }
-          }
-
-          if (ncallbacks == AFSCBMAX) {
-               theFids.AFSCBFids_len=ncallbacks;
-               theCBs.AFSCBs_len=ncallbacks;
-              for (j=0;j<server->naddrs;j++) {
-                if (!RXAFS_GiveUpCallBacks(server->conns[j], &theFids,
-                                          &theCBs))
-                  break;
-              }
-               ncallbacks=0;
-          }
-          memmove(&theFids.AFSCBFids_val[ncallbacks], &cb->fid,
-                  sizeof(struct AFSFid));
-          memmove(&theCBs.AFSCBs_val[ncallbacks], &cb->cb,
-                  sizeof(struct AFSCallBack));
-
-          theCBs.AFSCBs_val[ncallbacks].CallBackType = CB_DROPPED;
-         ncallbacks++;
-          if (cb->valid) {
-               f.cell=afs_cellbyid(cb->server->cell);
-               memcpy(&f.fid, &cb->fid, sizeof(struct afs_callback));
-               _StatInvalidate(&f);
-          }
-
-         cb->valid=0;
-     }
-     if (ncallbacks) {
-       theFids.AFSCBFids_len=ncallbacks;
-       theCBs.AFSCBs_len=ncallbacks;
-       for (j=0;j<server->naddrs;j++) {
-        if (!RXAFS_GiveUpCallBacks(server->conns[j], &theFids,
-                                  &theCBs))
-          break;
-       }
-       free(theFids.AFSCBFids_val);
-       free(theCBs.AFSCBs_val);
-     }
-     return 0;
-}
-
-int ReturnAllCallBacks(void)
+       }
+       if (cb->cb.ExpirationTime + cb->as_of < now) {
+           if (cb->valid) {
+               f.cell = afscp_CellById(cb->server->cell);
+               memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
+               _StatInvalidate(&f);
+           }
+           cb->valid = 0;
+           continue;
+       }
+       if (!inited) {
+           theFids.AFSCBFids_val = malloc(sizeof(struct AFSFid) * AFSCBMAX);
+           if (!theFids.AFSCBFids_val) {
+               return -1;
+           }
+           memset(theFids.AFSCBFids_val, 0,
+                  sizeof(struct AFSFid) * AFSCBMAX);
+           theCBs.AFSCBs_val = malloc(sizeof(struct AFSCallBack) * AFSCBMAX);
+           if (!theCBs.AFSCBs_val) {
+               free(theFids.AFSCBFids_val);
+               return -1;
+           }
+           memset(theCBs.AFSCBs_val, 0,
+                  sizeof(struct AFSCallBack) * AFSCBMAX);
+           inited = 1;
+       }
+
+       if (ncallbacks == AFSCBMAX) {
+           theFids.AFSCBFids_len = ncallbacks;
+           theCBs.AFSCBs_len = ncallbacks;
+           for (j = 0; j < server->naddrs; j++) {
+               c = afscp_ServerConnection(server, j);
+               if (c == NULL)
+                   break;
+               code = RXAFS_GiveUpCallBacks(c, &theFids, &theCBs);
+               if (code == 0)
+                   break;
+           }
+           ncallbacks = 0;
+       }
+       memmove(&theFids.AFSCBFids_val[ncallbacks], &cb->fid,
+               sizeof(struct AFSFid));
+       memmove(&theCBs.AFSCBs_val[ncallbacks], &cb->cb,
+               sizeof(struct AFSCallBack));
+
+       theCBs.AFSCBs_val[ncallbacks].CallBackType = CB_DROPPED;
+       ncallbacks++;
+       if (cb->valid) {
+           f.cell = afscp_CellById(cb->server->cell);
+           memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
+           _StatInvalidate(&f);
+       }
+
+       cb->valid = 0;
+    }
+    if (ncallbacks > 0) {
+       theFids.AFSCBFids_len = ncallbacks;
+       theCBs.AFSCBs_len = ncallbacks;
+       for (j = 0; j < server->naddrs; j++) {
+           c = afscp_ServerConnection(server, j);
+           if (c == NULL)
+               break;
+           code = RXAFS_GiveUpCallBacks(c, &theFids, &theCBs);
+           if (code == 0)
+               break;
+       }
+       free(theFids.AFSCBFids_val);
+       free(theCBs.AFSCBs_val);
+    }
+    return 0;
+}                              /* afscp_ReturnCallBacks */
+
+int
+afscp_ReturnAllCallBacks(void)
 {
-     struct afs_server *s;
-     int i;
-
-     for (i=0;(s=afs_serverbyindex(i));i++)
-          ReturnCallBacks(s);
-     return 0;
-}
-
-
-
-afs_int32 SRXAFSCB_CallBack(rxcall, Fids_Array, CallBack_Array)
-    struct rx_call *rxcall;
-    AFSCBFids *Fids_Array;
-    AFSCBs *CallBack_Array;
+    struct afscp_server *s;
+    int i;
 
-{ /*SRXAFSCB_CallBack*/
-     struct rx_connection *rxconn=rx_ConnectionOf(rxcall);
-     struct rx_peer *rxpeer=rx_PeerOf(rxconn);
-     struct afs_server *server=afs_anyserverbyaddr(rxpeer->host);
-     struct afs_callback *cb;
-     struct afs_venusfid f;
-     struct AFSFid *fid;
-     int i,j;
-
-     if (!server)
-          return 0;
-     for (i=0;i<afs_maxcallbacks;i++) {
-          cb=&allcallbacks[i];
-          if (cb->server != server)
-               continue;
-          for (j=0;j<Fids_Array->AFSCBFids_len;j++) {
-               fid=&Fids_Array->AFSCBFids_val[j];
-               if (fid->Volume == cb->fid.Volume &&
-                   fid->Vnode == cb->fid.Vnode &&
-                   fid->Unique == cb->fid.Unique)
-                    cb->valid = 0;
-               f.cell=afs_cellbyid(cb->server->cell);
-               memcpy(&f.fid, &cb->fid, sizeof(struct afs_venusfid));
-               _StatInvalidate(&f);
-          }
-     }
-
-    return(0);
-
-} /*SRXAFSCB_CallBack*/
-
-
-afs_int32 SRXAFSCB_InitCallBackState(rxcall)
-    struct rx_call *rxcall;
-
-{ /*SRXAFSCB_InitCallBackState*/
-     struct rx_connection *rxconn=rx_ConnectionOf(rxcall);
-     struct rx_peer *rxpeer=rx_PeerOf(rxconn);
-     struct afs_server *server=afs_anyserverbyaddr(rxpeer->host);
-     struct afs_callback *cb;
-     struct afs_venusfid f;
-     int i;
-
-     if (!server)
-          return 0;
-     for (i=0;i<afs_maxcallbacks;i++) {
-          cb=&allcallbacks[i];
-          if (cb->server != server)
-               continue;
-          if (cb->valid) {
-               f.cell=afs_cellbyid(cb->server->cell);
-               memcpy(&f.fid, &cb->fid, sizeof(struct afs_callback));
-               _StatInvalidate(&f);
-          }
-          cb->valid = 0;
-     }
-     return(0);
-
-} /*SRXAFSCB_InitCallBackState*/
-
-afs_int32 SRXAFSCB_Probe(rxcall)
-        struct rx_call *rxcall;
-
-{ /*SRXAFSCB_Probe*/
-    return(0);
-
-} /*SRXAFSCB_Probe*/
-
-
-afs_int32 SRXAFSCB_GetCE(rxcall)
-    struct rx_call *rxcall;
-
-{ /*SRXAFSCB_GetCE*/
-     return(0);
-} /*SRXAFSCB_GetCE*/
-
-afs_int32 SRXAFSCB_GetCE64(rxcall)
-    struct rx_call *rxcall;
-
-{ /*SRXAFSCB_GetCE*/
-     return(0);
-} /*SRXAFSCB_GetCE*/
-
-
-afs_int32 SRXAFSCB_GetLock(rxcall)
-    struct rx_call *rxcall;
+    if (allcallbacks == NULL)
+       return 0;
+    for (i = 0; (s = afscp_ServerByIndex(i)); i++) {
+       afscp_ReturnCallBacks(s);
+    }
+    free(allcallbacks);
+    allcallbacks = NULL;
+    afscp_maxcallbacks = 0;
+    afscp_cballoced = 0;
+    return 0;
+}                              /* afscp_ReturnAllCallBacks */
+
+/*!
+ * Handle a set of callbacks from the File Server.
+ *
+ * \param[in]  rxcall          Ptr to the associated Rx call structure.
+ * \param[in]  Fids_Array      Ptr to the set of Fids.
+ * \param[in]  CallBacks_Array Ptr to the set of callbacks.
+ *
+ * \post Returns RXGEN_SUCCESS on success, Error value otherwise.
+ *
+ */
+afs_int32
+SRXAFSCB_CallBack(struct rx_call * rxcall, AFSCBFids * Fids_Array,
+                 AFSCBs * CallBack_Array)
+{
+    struct rx_connection *rxconn = rx_ConnectionOf(rxcall);
+    struct rx_peer *rxpeer = rx_PeerOf(rxconn);
+    struct afscp_server *server = afscp_AnyServerByAddr(rxpeer->host);
+    struct afscp_callback *cb;
+    struct afscp_venusfid f;
+    struct AFSFid *fid;
+    int i, j;
+
+    if (server == NULL) {
+       return 0;
+    }
+    for (i = 0; i < afscp_maxcallbacks; i++) {
+       cb = &allcallbacks[i];
+       if (cb->server != server)
+           continue;
+       for (j = 0; j < Fids_Array->AFSCBFids_len; j++) {
+           fid = &Fids_Array->AFSCBFids_val[j];
+           if ((fid->Volume == cb->fid.Volume) &&
+               (fid->Vnode == cb->fid.Vnode) &&
+               (fid->Unique == cb->fid.Unique))
+               cb->valid = 0;
+           f.cell = afscp_CellById(cb->server->cell);
+           memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
+           _StatInvalidate(&f);
+       }
+    }
 
-{ /*SRXAFSCB_GetLock*/
-    return(0);
-
-} /*SRXAFSCB_GetLock*/
-afs_int32 SRXAFSCB_XStatsVersion(rxcall)
-    struct rx_call *rxcall;
-
-{ /*SRXAFSCB_XStatsVersion*/
-    return(0);
-
-} /*SRXAFSCB_XStatsVersion*/
-
-afs_int32 SRXAFSCB_GetXStats(rxcall)
-    struct rx_call *rxcall;
-
-{ /*SRXAFSCB_GetXStats*/
-     return(0);
-} /*SRXAFSCB_GetXStats*/
-
-int SRXAFSCB_InitCallBackState2(rxcall, addr)
-struct rx_call *rxcall;
-struct interfaceAddr * addr;
+    return RXGEN_SUCCESS;
+}                              /*SRXAFSCB_CallBack */
+
+/*!
+ * Initialize callback state on this ``Cache Manager''.
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ *
+ * \post Returns RXGEN_SUCCESS on success, Error value otherwise.
+ *
+ * \note This will definitely be called by the File Server (exactly once),
+ *       since it will think we are another new ``Cache Manager''.
+ */
+afs_int32
+SRXAFSCB_InitCallBackState(struct rx_call * rxcall)
+{
+    struct rx_connection *rxconn = rx_ConnectionOf(rxcall);
+    struct rx_peer *rxpeer = rx_PeerOf(rxconn);
+    struct afscp_server *server = afscp_AnyServerByAddr(rxpeer->host);
+    struct afscp_callback *cb;
+    struct afscp_venusfid f;
+    int i;
+
+    if (server == NULL) {
+       return 0;
+    }
+    for (i = 0; i < afscp_maxcallbacks; i++) {
+       cb = &allcallbacks[i];
+       if (cb->server != server)
+           continue;
+       if (cb->valid) {
+           f.cell = afscp_CellById(cb->server->cell);
+           memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
+           _StatInvalidate(&f);
+       }
+       cb->valid = 0;
+    }
+    return RXGEN_SUCCESS;
+}                              /* SRXAFSCB_InitCallBackState */
+
+/*!
+ * Respond to a probe from the File Server.
+ *
+ * \param[in] rxcall   Ptr to the associated Rx call structure.
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ * \note If a File Server doesn't hear from you every so often, it will
+ *       send you a probe to make sure you're there, just like any other
+ *      ``Cache Manager'' it's keeping track of.
+ *
+ */
+afs_int32
+SRXAFSCB_Probe(struct rx_call * rxcall)
+{
+    return RXGEN_SUCCESS;
+}                              /* SRXAFSCB_Probe */
+
+/*!
+ * Respond minimally to a request for returning the contents of
+ * a cache lock, since someone out there thinks you're a Cache
+ * Manager.
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ * \param[in]  index
+ * \param[out] lock
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_GetLock(struct rx_call * rxcall, afs_int32 index, AFSDBLock * lock)
+{
+    return RXGEN_SUCCESS;
+
+}                              /*SRXAFSCB_GetLock */
+
+/*!
+ * Respond minimally to a request for returning the contents of
+ * a cache entry, since someone out there thinks you're a Cache
+ * Manager.
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ * \param[in]  index
+ * \param[out] ce      Ptr to cache entry
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_GetCE(struct rx_call * rxcall, afs_int32 index, AFSDBCacheEntry * ce)
+{
+    return RXGEN_SUCCESS;
+}                              /* SRXAFSCB_GetCE */
+
+/*!
+ * Respond minimally to a request for returning the contents of
+ * a cache entry, since someone out there thinks you're a Cache
+ * Manager. (64-bit version, though same as SRXAFSCB_GetCE())
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ * \param[in]  index
+ * \param[out] ce      Ptr to cache entry
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_GetCE64(struct rx_call * rxcall, afs_int32 index,
+                AFSDBCacheEntry64 * ce)
+{
+    return RXGEN_SUCCESS;
+}                              /*SRXAFSCB_GetCE */
+
+/*!
+ * Respond minimally to a request for fetching the version of
+ * extended Cache Manager statistics offered, since someone out
+ * there thinks you're a Cache Manager.
+ *
+ * \param[in]  rxcall          Ptr to the associated Rx call structure
+ * \param[out] versionNumberP
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_XStatsVersion(struct rx_call * rxcall, afs_int32 * versionNumberP)
+{
+    return RXGEN_SUCCESS;
+}                              /*SRXAFSCB_XStatsVersion */
+
+/*!
+ * Respond minimally to a request for returning extended
+ * statistics for a Cache Manager, since someone out there thinks
+ * you're a Cache Manager.
+ *
+ * \param[in]  z_call                  Ptr to the associated Rx call structure
+ * \param[in]  clientVersionNumber
+ * \param[in]  collectionNumber
+ * \param[out] srvVersionNumberP
+ * \param[out] timeP
+ * \param[out] dataP
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_GetXStats(struct rx_call * z_call, afs_int32 clientVersionNumber,
+                  afs_int32 collectionNumber, afs_int32 * srvVersionNumberP,
+                  afs_int32 * timeP, AFSCB_CollData * dataP)
+{
+    return RXGEN_SUCCESS;
+}                              /*SRXAFSCB_GetXStats */
+
+/*!
+ * This routine was used in the AFS 3.5 beta release, but not anymore.
+ * It has since been replaced by SRXAFSCB_InitCallBackState3.
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ * \param[out] addr    Ptr to return the list of interfaces for this client
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_InitCallBackState2(struct rx_call * rxcall,
+                           struct interfaceAddr * addr)
 {
     return RXGEN_OPCODE;
-}
-
-int SRXAFSCB_WhoAreYou(rxcall, addr)
-struct rx_call *rxcall;
-struct interfaceAddr *addr;
+}                              /* SRXAFSCB_InitCallBackState2 */
+
+/*!
+ *
+ * \param      rxcall  Ptr to the associated Rx call structure.
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_TellMeAboutYourself(struct rx_call * a_call,
+                            struct interfaceAddr * addr,
+                            Capabilities * capabilities)
 {
-    XDR x;
-    if ( rxcall && addr )
-    {
-        if (!afs_cb_inited) init_afs_cb();
-        *addr = afs_cb_interface;
+#ifdef AFS_NT40_ENV
+    int code;
+    int cm_noIPAddr;           /* number of client network interfaces */
+    int cm_IPAddr[CM_MAXINTERFACE_ADDR];       /* client's IP address in host order */
+    int cm_SubnetMask[CM_MAXINTERFACE_ADDR];   /* client's subnet mask in host order */
+    int cm_NetMtu[CM_MAXINTERFACE_ADDR];       /* client's MTU sizes */
+    int cm_NetFlags[CM_MAXINTERFACE_ADDR];     /* network flags */
+    int i;
+
+    cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+    code = syscfg_GetIFInfo(&cm_noIPAddr,
+                           cm_IPAddr, cm_SubnetMask, cm_NetMtu, cm_NetFlags);
+    if (code > 0) {
+       /* return all network interface addresses */
+       addr->numberOfInterfaces = cm_noIPAddr;
+       for (i = 0; i < cm_noIPAddr; i++) {
+           addr->addr_in[i] = cm_IPAddr[i];
+           addr->subnetmask[i] = cm_SubnetMask[i];
+           addr->mtu[i] = (rx_mtu == -1
+                           || (rx_mtu != -1
+                               && cm_NetMtu[i] <
+                               rx_mtu)) ? cm_NetMtu[i] : rx_mtu;
+       }
+    } else {
+       addr->numberOfInterfaces = 0;
+    }
+#else
+    if (a_call && addr) {
+       if (!afs_cb_inited)
+           init_afs_cb();
+       *addr = afs_cb_interface;
     }
-#ifdef STRANGEDEBUG
-    xdrrx_create(&x, rxcall, XDR_ENCODE);
-    xdr_interfaceAddr(&x, addr);
-    rx_Write(rxcall,"",0);
-    rxi_FlushWrite(rxcall);
-    rx_EndCall(rxcall, 0);
-    IOMGR_Sleep(10);
-    IOMGR_Sleep(600);
 #endif
-    return(0);
-}
-
-int SRXAFSCB_InitCallBackState3(rxcall, uuidp)
-struct rx_call *rxcall;
-afsUUID *uuidp;
+    if (capabilities != NULL) {
+       afs_uint32 *dataBuffP;
+       afs_int32 dataBytes;
+
+       dataBytes = 1 * sizeof(afs_uint32);
+       dataBuffP = (afs_uint32 *) xdr_alloc(dataBytes);
+       dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
+       capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
+       capabilities->Capabilities_val = dataBuffP;
+    }
+    return RXGEN_SUCCESS;
+}                              /* SRXAFSCB_TellMeAboutYourself */
+
+/*!
+ * Routine called by the server-side callback RPC interface to
+ * obtain a unique identifier for the client. The server uses
+ * this identifier to figure out whether or not two RX connections
+ * are from the same client, and to find out which addresses go
+ * with which clients.
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ * \param[out] addr    Ptr to return the list of interfaces for this client
+ *
+ * \post Returns output of TellMeAboutYourself (which
+ *       should be RXGEN_SUCCESS).
+ *
+ */
+afs_int32
+SRXAFSCB_WhoAreYou(struct rx_call * rxcall, struct interfaceAddr * addr)
 {
-     struct rx_connection *rxconn=rx_ConnectionOf(rxcall);
-     struct rx_peer *rxpeer=rx_PeerOf(rxconn);
-     struct afs_server *server=afs_anyserverbyaddr(rxpeer->host);
-     struct afs_callback *cb;
-     struct afs_venusfid f;
-     int i;
-
-     if (!server)
-          return 0;
-     for (i=0;i<afs_maxcallbacks;i++) {
-          cb=&allcallbacks[i];
-          if (cb->server != server)
-               continue;
-          if (cb->valid) {
-               f.cell=afs_cellbyid(cb->server->cell);
-               memcpy(&f.fid, &cb->fid, sizeof(struct afs_callback));
-               _StatInvalidate(&f);
-          }
-          cb->valid = 0;
-     }
-     return(0);
-}
-int SRXAFSCB_ProbeUuid(rxcall, uuidp)
-struct rx_call *rxcall;
-afsUUID *uuidp;
+    return SRXAFSCB_TellMeAboutYourself(rxcall, addr, NULL);
+}                              /* SRXAFSCB_WhoAreYou */
+
+/*!
+ * Routine called by the server-side callback RPC interface to
+ * implement clearing all callbacks from this host.
+ *
+ * \param[in]  rxcall          Ptr to the associated Rx call structure.
+ * \param[in]  serverUuid      Ptr to UUID
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_InitCallBackState3(struct rx_call * rxcall, afsUUID * serverUuid)
+{
+    struct rx_connection *rxconn = rx_ConnectionOf(rxcall);
+    struct rx_peer *rxpeer = rx_PeerOf(rxconn);
+    struct afscp_server *server = afscp_AnyServerByAddr(rxpeer->host);
+    struct afscp_callback *cb;
+    struct afscp_venusfid f;
+    int i;
+
+    if (server == NULL) {
+       return 0;
+    }
+    for (i = 0; i < afscp_maxcallbacks; i++) {
+       cb = &allcallbacks[i];
+       if (cb->server != server)
+           continue;
+       if (cb->valid) {
+           f.cell = afscp_CellById(cb->server->cell);
+           memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
+           _StatInvalidate(&f);
+       }
+       cb->valid = 0;
+    }
+    return RXGEN_SUCCESS;
+}                              /* SRXAFSCB_InitCallBackState3 */
+
+/*!
+ * Routine called by the server-side callback RPC interface to
+ * implement ``probing'' the Cache Manager, just making sure it's
+ * still there is still the same client it used to be.
+ *
+ * \param      rxcall          Ptr to the associated Rx call structure.
+ * \param      clientUuid      Ptr to UUID that must match the client's UUID
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_ProbeUuid(struct rx_call * rxcall, afsUUID * clientUuid)
 {
     int code = 0;
-    if (!afs_cb_inited) init_afs_cb();
-    if (!afs_uuid_equal(uuidp, &afs_cb_interface.uuid))
-        code = 1; /* failure */
-#ifdef STRANGEDEBUG
-    rx_EndCall(rxcall,code);
-    IOMGR_Sleep(600);
-#endif
+    if (!afs_cb_inited)
+       init_afs_cb();
+    if (!afs_uuid_equal(clientUuid, &afs_cb_interface.uuid))
+       code = 1;               /* failure */
     return code;
-}
-int SRXAFSCB_GetServerPrefs(
-    struct rx_call *a_call,
-    afs_int32 a_index,
-    afs_int32 *a_srvr_addr,
-    afs_int32 *a_srvr_rank)
+}                              /* SRXAFSCB_ProbeUuid */
+
+/*!
+ * Routine to list server preferences used by this client.
+ *
+ * \param[in]  a_call          Ptr to Rx call on which this request came in.
+ * \param[in]  a_index         Input server index
+ * \param[out] a_srvr_addr     Output server address (0xffffffff on last server)
+ * \param[out] a_srvr_rank     Output server rank
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+afs_int32
+SRXAFSCB_GetServerPrefs(struct rx_call * a_call, afs_int32 a_index,
+                       afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
 {
     *a_srvr_addr = 0xffffffff;
     *a_srvr_rank = 0xffffffff;
-    return 0;
-}
-
-int SRXAFSCB_GetCellServDB(
-    struct rx_call *a_call,
-    afs_int32 a_index,
-    char **a_name,
-    afs_int32 *a_hosts)
+    return RXGEN_SUCCESS;
+}                              /* SRXAFSCB_GetServerPrefs */
+
+/*!
+ * Routine to list cells configured for this client
+ *
+ * \param[in]  a_call  Ptr to Rx call on which this request came in.
+ * \param[in]  a_index Input cell index
+ * \param[out] a_name  Output cell name ("" on last cell)
+ * \param[out] a_hosts Output cell database servers
+ *
+ * \post Returns RXGEN_OPCODE (always)
+ *
+ */
+afs_int32
+SRXAFSCB_GetCellServDB(struct rx_call * a_call, afs_int32 a_index,
+                      char **a_name, afs_int32 * a_hosts)
 {
     return RXGEN_OPCODE;
-}
-
-int SRXAFSCB_GetLocalCell(
-    struct rx_call *a_call,
-    char **a_name)
+}                              /* SRXAFSCB_GetCellServDB */
+
+/*!
+ * Routine to return name of client's local cell
+ *
+ * \param[in]  a_call  Ptr to Rx call on which this request came in.
+ * \param[out] a_name  Output cell name
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+int
+SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
 {
     return RXGEN_OPCODE;
-}
-
-int SRXAFSCB_GetCacheConfig(
-    struct rx_call *a_call,
-    afs_uint32 callerVersion,
-    afs_uint32 *serverVersion,
-    afs_uint32 *configCount,
-    cacheConfig *config)
+}                              /* SRXAFSCB_GetLocalCell */
+
+/*!
+ * Routine to return parameters used to initialize client cache.
+ * Client may request any format version. Server may not return
+ * format version greater than version requested by client.
+ *
+ * \param[in]  a_call          Ptr to Rx call on which this request came in.
+ * \param[in]  callerVersion   Data format version desired by the client.
+ * \param[out] serverVersion   Data format version of output data.
+ * \param[out] configCount     Number bytes allocated for output data.
+ * \param[out] config          Client cache configuration.
+ *
+ * \post Returns RXGEN_SUCCESS (always)
+ *
+ */
+int
+SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
+                       afs_uint32 * serverVersion, afs_uint32 * configCount,
+                       cacheConfig * config)
 {
     return RXGEN_OPCODE;
-}
-int SRXAFSCB_GetCellByNum(
-    struct rx_call *a_call,
-    afs_int32 a_index,
-    char **a_name,
-    afs_int32 *a_hosts)
+}                              /* SRXAFSCB_GetCacheConfig */
+
+/*!
+
+ *
+ * \param[in]  rxcall  Ptr to the associated Rx call structure.
+ *
+ * \post Returns RXGEN_OPCODE (always)
+ *
+ */
+int
+SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_index,
+                     char **a_name, afs_int32 * a_hosts)
 {
     return RXGEN_OPCODE;
-}
-#ifdef AFS_64BIT_CLIENT
-afs_int32
-SRXAFSCB_TellMeAboutYourself(struct rx_call * rxcall,
-                             struct interfaceAddr * addr,
-                             Capabilities * capabilities)
-{
-    if ( rxcall && addr )
-    {
-        if (!afs_cb_inited) init_afs_cb();
-        *addr = afs_cb_interface;
-    }
-    return(0);
-}
-#endif
+}                              /* SRXAFSCB_GetCellByNum */