Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / libafscp / afscp_callback.c
blob3bb8062821aa87a31067d3cd2dc3b61634d8c440
1 /* AUTORIGHTS
2 Copyright (C) 2003 - 2010 Chaskiel Grundman
3 All rights reserved
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <afsconfig.h>
28 #include <afs/param.h>
30 #include <afs/afsutil.h>
32 #ifdef AFS_NT40_ENV
33 #include <windows.h>
34 #include <rpc.h>
35 #include <afs/cm_server.h>
36 #include <WINNT/syscfg.h>
37 #endif
39 #include <afs/afsutil.h>
40 #include "afscp.h"
41 #include "afscp_internal.h"
43 int afs_cb_inited = 0;
44 struct interfaceAddr afs_cb_interface;
45 static int afscp_maxcallbacks = 0, afscp_cballoced = 0;
46 struct afscp_callback *allcallbacks = NULL;
48 /*!
49 * Initialize the callback interface structure
51 static int
52 init_afs_cb(void)
54 int cm_noIPAddr; /* number of client network interfaces */
55 int i;
56 #ifdef AFS_NT40_ENV
58 * This Windows section was pulled in from changes to src/venus/afsio.c but is
59 * untested here and may be unnecessary if rx_getAllAddr() can be used on that
60 * platform. However, there was already an ifdef here surrounding UuidCreate().
62 long rx_mtu = -1;
63 int code;
64 int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
65 int cm_SubnetMask[CM_MAXINTERFACE_ADDR]; /* client's subnet mask in host order */
66 int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
67 int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
69 UuidCreate((UUID *) & afs_cb_interface.uuid);
70 cm_noIPAddr = CM_MAXINTERFACE_ADDR;
71 code = syscfg_GetIFInfo(&cm_noIPAddr,
72 cm_IPAddr, cm_SubnetMask, cm_NetMtu, cm_NetFlags);
73 if (code > 0) {
74 /* return all network interface addresses */
75 afs_cb_interface.numberOfInterfaces = cm_noIPAddr;
76 for (i = 0; i < cm_noIPAddr; i++) {
77 afs_cb_interface.addr_in[i] = cm_IPAddr[i];
78 afs_cb_interface.subnetmask[i] = cm_SubnetMask[i];
79 afs_cb_interface.mtu[i] = (rx_mtu == -1
80 || (rx_mtu != -1
81 && cm_NetMtu[i] <
82 rx_mtu)) ? cm_NetMtu[i] : rx_mtu;
84 } else {
85 afs_cb_interface.numberOfInterfaces = 0;
87 #else
88 afs_uuid_create(&afs_cb_interface.uuid);
89 cm_noIPAddr =
90 rx_getAllAddr((afs_uint32 *) afs_cb_interface.addr_in,
91 AFS_MAX_INTERFACE_ADDR);
92 if (cm_noIPAddr < 0)
93 afs_cb_interface.numberOfInterfaces = 0;
94 else {
95 afs_cb_interface.numberOfInterfaces = cm_noIPAddr;
96 /* we expect these in host byte order */
97 for (i = 0; i < cm_noIPAddr; i++)
98 afs_cb_interface.addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
100 #endif
101 afs_cb_inited = 1;
102 return 0;
103 } /* init_afs_cb */
106 afscp_FindCallBack(const struct afscp_venusfid *f,
107 const struct afscp_server *server,
108 struct afscp_callback **ret)
110 int i;
111 struct afscp_callback *use = NULL, *cb;
112 time_t now;
113 struct afscp_venusfid fid;
115 *ret = NULL;
117 time(&now);
118 for (i = 0; i < afscp_maxcallbacks; i++) {
119 cb = &allcallbacks[i];
120 if ((f->fid.Volume == cb->fid.Volume) &&
121 (f->fid.Vnode == cb->fid.Vnode) &&
122 (f->fid.Unique == cb->fid.Unique)) {
123 if (server && (cb->server != server))
124 continue;
125 use = cb;
126 break;
129 if (!use)
130 return -1;
132 if (use->cb.ExpirationTime + use->as_of < now) {
133 if (use->valid) {
134 fid.cell = afscp_CellById(use->server->cell);
135 memcpy(&fid.fid, &use->fid, sizeof(struct AFSFid));
136 _StatInvalidate(&fid);
138 use->valid = 0;
141 if (use->valid)
142 *ret = use;
143 else
144 return -1;
146 return 0;
150 afscp_AddCallBack(const struct afscp_server *server,
151 const struct AFSFid *fid,
152 const struct AFSFetchStatus *fst,
153 const struct AFSCallBack *cb, const time_t as_of)
155 int i;
156 struct afscp_callback *use = NULL, *newlist;
157 struct afscp_venusfid f;
158 time_t now;
160 time(&now);
162 for (i = 0; i < afscp_maxcallbacks; i++) {
163 if (allcallbacks[i].cb.ExpirationTime + allcallbacks[i].as_of < now) {
164 if (allcallbacks[i].valid) {
165 f.cell = afscp_CellById(allcallbacks[i].server->cell);
166 memcpy(&f.fid, &allcallbacks[i].fid, sizeof(struct AFSFid));
167 _StatInvalidate(&f);
169 allcallbacks[i].valid = 0;
172 if (allcallbacks[i].valid == 0)
173 use = &allcallbacks[i];
174 if ((allcallbacks[i].server == server) &&
175 (fid->Volume == allcallbacks[i].fid.Volume) &&
176 (fid->Vnode == allcallbacks[i].fid.Vnode) &&
177 (fid->Unique == allcallbacks[i].fid.Unique)) {
178 use = &allcallbacks[i];
179 break;
182 if (use == NULL) {
183 if (afscp_maxcallbacks >= afscp_cballoced) {
184 if (afscp_cballoced != 0)
185 afscp_cballoced = afscp_cballoced * 2;
186 else
187 afscp_cballoced = 4;
188 newlist = realloc(allcallbacks, afscp_cballoced *
189 sizeof(struct afscp_callback));
190 if (newlist == NULL) {
191 return -1;
193 allcallbacks = newlist;
195 use = &allcallbacks[afscp_maxcallbacks++];
197 use->valid = 1;
198 use->server = server;
199 memmove(&use->fid, fid, sizeof(struct AFSFid));
200 memmove(&use->cb, cb, sizeof(struct AFSCallBack));
201 use->as_of = as_of;
202 f.cell = afscp_CellById(server->cell);
203 memcpy(&f.fid, fid, sizeof(struct AFSFid));
204 _StatStuff(&f, fst);
205 return 0;
206 } /* afscp_AddCallBack */
209 afscp_RemoveCallBack(const struct afscp_server *server,
210 const struct afscp_venusfid *f)
212 struct afscp_callback *cb;
213 int i;
215 _StatInvalidate(f);
216 if (server == NULL) {
217 return 0;
219 for (i = 0; i < afscp_maxcallbacks; i++) {
220 cb = &allcallbacks[i];
221 if ((cb->server == server) &&
222 (f->fid.Volume == cb->fid.Volume) &&
223 (f->fid.Vnode == cb->fid.Vnode) &&
224 (f->fid.Unique == cb->fid.Unique)) {
225 cb->valid = 0;
226 break;
229 return 0;
230 } /* afscp_ReturnCallBacks */
233 afscp_ReturnCallBacks(const struct afscp_server *server)
235 struct AFSCBFids theFids;
236 struct AFSCBs theCBs;
237 struct afscp_callback *cb;
238 struct afscp_venusfid f;
239 struct rx_connection *c;
240 int inited = 0;
241 int ncallbacks = 0;
242 int i, j, code;
243 time_t now;
245 time(&now);
247 for (i = 0; i < afscp_maxcallbacks; i++) {
248 cb = &allcallbacks[i];
249 if (cb->server != server) {
250 continue;
252 if (cb->cb.ExpirationTime + cb->as_of < now) {
253 if (cb->valid) {
254 f.cell = afscp_CellById(cb->server->cell);
255 memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
256 _StatInvalidate(&f);
258 cb->valid = 0;
259 continue;
261 if (!inited) {
262 theFids.AFSCBFids_val = malloc(sizeof(struct AFSFid) * AFSCBMAX);
263 if (!theFids.AFSCBFids_val) {
264 return -1;
266 memset(theFids.AFSCBFids_val, 0,
267 sizeof(struct AFSFid) * AFSCBMAX);
268 theCBs.AFSCBs_val = malloc(sizeof(struct AFSCallBack) * AFSCBMAX);
269 if (!theCBs.AFSCBs_val) {
270 free(theFids.AFSCBFids_val);
271 return -1;
273 memset(theCBs.AFSCBs_val, 0,
274 sizeof(struct AFSCallBack) * AFSCBMAX);
275 inited = 1;
278 if (ncallbacks == AFSCBMAX) {
279 theFids.AFSCBFids_len = ncallbacks;
280 theCBs.AFSCBs_len = ncallbacks;
281 for (j = 0; j < server->naddrs; j++) {
282 c = afscp_ServerConnection(server, j);
283 if (c == NULL)
284 break;
285 code = RXAFS_GiveUpCallBacks(c, &theFids, &theCBs);
286 if (code == 0)
287 break;
289 ncallbacks = 0;
291 memmove(&theFids.AFSCBFids_val[ncallbacks], &cb->fid,
292 sizeof(struct AFSFid));
293 memmove(&theCBs.AFSCBs_val[ncallbacks], &cb->cb,
294 sizeof(struct AFSCallBack));
296 theCBs.AFSCBs_val[ncallbacks].CallBackType = CB_DROPPED;
297 ncallbacks++;
298 if (cb->valid) {
299 f.cell = afscp_CellById(cb->server->cell);
300 memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
301 _StatInvalidate(&f);
304 cb->valid = 0;
306 if (ncallbacks > 0) {
307 theFids.AFSCBFids_len = ncallbacks;
308 theCBs.AFSCBs_len = ncallbacks;
309 for (j = 0; j < server->naddrs; j++) {
310 c = afscp_ServerConnection(server, j);
311 if (c == NULL)
312 break;
313 code = RXAFS_GiveUpCallBacks(c, &theFids, &theCBs);
314 if (code == 0)
315 break;
317 free(theFids.AFSCBFids_val);
318 free(theCBs.AFSCBs_val);
320 return 0;
321 } /* afscp_ReturnCallBacks */
324 afscp_ReturnAllCallBacks(void)
326 struct afscp_server *s;
327 int i;
329 if (allcallbacks == NULL)
330 return 0;
331 for (i = 0; (s = afscp_ServerByIndex(i)); i++) {
332 afscp_ReturnCallBacks(s);
334 free(allcallbacks);
335 allcallbacks = NULL;
336 afscp_maxcallbacks = 0;
337 afscp_cballoced = 0;
338 return 0;
339 } /* afscp_ReturnAllCallBacks */
342 * Handle a set of callbacks from the File Server.
344 * \param[in] rxcall Ptr to the associated Rx call structure.
345 * \param[in] Fids_Array Ptr to the set of Fids.
346 * \param[in] CallBacks_Array Ptr to the set of callbacks.
348 * \post Returns RXGEN_SUCCESS on success, Error value otherwise.
351 afs_int32
352 SRXAFSCB_CallBack(struct rx_call * rxcall, AFSCBFids * Fids_Array,
353 AFSCBs * CallBack_Array)
355 struct rx_connection *rxconn = rx_ConnectionOf(rxcall);
356 struct rx_peer *rxpeer = rx_PeerOf(rxconn);
357 struct afscp_server *server = afscp_AnyServerByAddr(rx_HostOf(rxpeer));
358 struct afscp_callback *cb;
359 struct afscp_venusfid f;
360 struct AFSFid *fid;
361 int i;
362 unsigned int j;
364 if (server == NULL) {
365 return 0;
367 for (i = 0; i < afscp_maxcallbacks; i++) {
368 cb = &allcallbacks[i];
369 if (cb->server != server)
370 continue;
371 for (j = 0; j < Fids_Array->AFSCBFids_len; j++) {
372 fid = &Fids_Array->AFSCBFids_val[j];
373 if ((fid->Volume == cb->fid.Volume) &&
374 (fid->Vnode == cb->fid.Vnode) &&
375 (fid->Unique == cb->fid.Unique))
376 cb->valid = 0;
377 f.cell = afscp_CellById(cb->server->cell);
378 memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
379 _StatInvalidate(&f);
383 return RXGEN_SUCCESS;
384 } /*SRXAFSCB_CallBack */
387 * Initialize callback state on this ``Cache Manager''.
389 * \param[in] rxcall Ptr to the associated Rx call structure.
391 * \post Returns RXGEN_SUCCESS on success, Error value otherwise.
393 * \note This will definitely be called by the File Server (exactly once),
394 * since it will think we are another new ``Cache Manager''.
396 afs_int32
397 SRXAFSCB_InitCallBackState(struct rx_call * rxcall)
399 struct rx_connection *rxconn = rx_ConnectionOf(rxcall);
400 struct rx_peer *rxpeer = rx_PeerOf(rxconn);
401 struct afscp_server *server = afscp_AnyServerByAddr(rx_HostOf(rxpeer));
402 struct afscp_callback *cb;
403 struct afscp_venusfid f;
404 int i;
406 if (server == NULL) {
407 return 0;
409 for (i = 0; i < afscp_maxcallbacks; i++) {
410 cb = &allcallbacks[i];
411 if (cb->server != server)
412 continue;
413 if (cb->valid) {
414 f.cell = afscp_CellById(cb->server->cell);
415 memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
416 _StatInvalidate(&f);
418 cb->valid = 0;
420 return RXGEN_SUCCESS;
421 } /* SRXAFSCB_InitCallBackState */
424 * Respond to a probe from the File Server.
426 * \param[in] rxcall Ptr to the associated Rx call structure.
428 * \post Returns RXGEN_SUCCESS (always)
430 * \note If a File Server doesn't hear from you every so often, it will
431 * send you a probe to make sure you're there, just like any other
432 * ``Cache Manager'' it's keeping track of.
435 afs_int32
436 SRXAFSCB_Probe(struct rx_call * rxcall)
438 return RXGEN_SUCCESS;
439 } /* SRXAFSCB_Probe */
442 * Respond minimally to a request for returning the contents of
443 * a cache lock, since someone out there thinks you're a Cache
444 * Manager.
446 * \param[in] rxcall Ptr to the associated Rx call structure.
447 * \param[in] index
448 * \param[out] lock
450 * \post Returns RXGEN_SUCCESS (always)
453 afs_int32
454 SRXAFSCB_GetLock(struct rx_call * rxcall, afs_int32 index, AFSDBLock * lock)
456 return RXGEN_SUCCESS;
458 } /*SRXAFSCB_GetLock */
461 * Respond minimally to a request for returning the contents of
462 * a cache entry, since someone out there thinks you're a Cache
463 * Manager.
465 * \param[in] rxcall Ptr to the associated Rx call structure.
466 * \param[in] index
467 * \param[out] ce Ptr to cache entry
469 * \post Returns RXGEN_SUCCESS (always)
472 afs_int32
473 SRXAFSCB_GetCE(struct rx_call * rxcall, afs_int32 index, AFSDBCacheEntry * ce)
475 return RXGEN_SUCCESS;
476 } /* SRXAFSCB_GetCE */
479 * Respond minimally to a request for returning the contents of
480 * a cache entry, since someone out there thinks you're a Cache
481 * Manager. (64-bit version, though same as SRXAFSCB_GetCE())
483 * \param[in] rxcall Ptr to the associated Rx call structure.
484 * \param[in] index
485 * \param[out] ce Ptr to cache entry
487 * \post Returns RXGEN_SUCCESS (always)
490 afs_int32
491 SRXAFSCB_GetCE64(struct rx_call * rxcall, afs_int32 index,
492 AFSDBCacheEntry64 * ce)
494 return RXGEN_SUCCESS;
495 } /*SRXAFSCB_GetCE */
498 * Respond minimally to a request for fetching the version of
499 * extended Cache Manager statistics offered, since someone out
500 * there thinks you're a Cache Manager.
502 * \param[in] rxcall Ptr to the associated Rx call structure
503 * \param[out] versionNumberP
505 * \post Returns RXGEN_SUCCESS (always)
508 afs_int32
509 SRXAFSCB_XStatsVersion(struct rx_call * rxcall, afs_int32 * versionNumberP)
511 return RXGEN_SUCCESS;
512 } /*SRXAFSCB_XStatsVersion */
515 * Respond minimally to a request for returning extended
516 * statistics for a Cache Manager, since someone out there thinks
517 * you're a Cache Manager.
519 * \param[in] z_call Ptr to the associated Rx call structure
520 * \param[in] clientVersionNumber
521 * \param[in] collectionNumber
522 * \param[out] srvVersionNumberP
523 * \param[out] timeP
524 * \param[out] dataP
526 * \post Returns RXGEN_SUCCESS (always)
529 afs_int32
530 SRXAFSCB_GetXStats(struct rx_call * z_call, afs_int32 clientVersionNumber,
531 afs_int32 collectionNumber, afs_int32 * srvVersionNumberP,
532 afs_int32 * timeP, AFSCB_CollData * dataP)
534 return RXGEN_SUCCESS;
535 } /*SRXAFSCB_GetXStats */
538 * This routine was used in the AFS 3.5 beta release, but not anymore.
539 * It has since been replaced by SRXAFSCB_InitCallBackState3.
541 * \param[in] rxcall Ptr to the associated Rx call structure.
542 * \param[out] addr Ptr to return the list of interfaces for this client
544 * \post Returns RXGEN_SUCCESS (always)
547 afs_int32
548 SRXAFSCB_InitCallBackState2(struct rx_call * rxcall,
549 struct interfaceAddr * addr)
551 return RXGEN_OPCODE;
552 } /* SRXAFSCB_InitCallBackState2 */
556 * \param rxcall Ptr to the associated Rx call structure.
558 * \post Returns RXGEN_SUCCESS (always)
561 afs_int32
562 SRXAFSCB_TellMeAboutYourself(struct rx_call * a_call,
563 struct interfaceAddr * addr,
564 Capabilities * capabilities)
566 #ifdef AFS_NT40_ENV
567 int code;
568 int cm_noIPAddr; /* number of client network interfaces */
569 int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */
570 int cm_SubnetMask[CM_MAXINTERFACE_ADDR]; /* client's subnet mask in host order */
571 int cm_NetMtu[CM_MAXINTERFACE_ADDR]; /* client's MTU sizes */
572 int cm_NetFlags[CM_MAXINTERFACE_ADDR]; /* network flags */
573 int i;
575 cm_noIPAddr = CM_MAXINTERFACE_ADDR;
576 code = syscfg_GetIFInfo(&cm_noIPAddr,
577 cm_IPAddr, cm_SubnetMask, cm_NetMtu, cm_NetFlags);
578 if (code > 0) {
579 /* return all network interface addresses */
580 addr->numberOfInterfaces = cm_noIPAddr;
581 for (i = 0; i < cm_noIPAddr; i++) {
582 addr->addr_in[i] = cm_IPAddr[i];
583 addr->subnetmask[i] = cm_SubnetMask[i];
584 addr->mtu[i] = cm_NetMtu[i];
586 } else {
587 addr->numberOfInterfaces = 0;
589 #else
590 if (a_call && addr) {
591 if (!afs_cb_inited)
592 init_afs_cb();
593 *addr = afs_cb_interface;
595 #endif
596 if (capabilities != NULL) {
597 afs_uint32 *dataBuffP;
598 afs_int32 dataBytes;
600 dataBytes = 1 * sizeof(afs_uint32);
601 dataBuffP = (afs_uint32 *) xdr_alloc(dataBytes);
602 dataBuffP[0] = CLIENT_CAPABILITY_ERRORTRANS;
603 capabilities->Capabilities_len = dataBytes / sizeof(afs_uint32);
604 capabilities->Capabilities_val = dataBuffP;
606 return RXGEN_SUCCESS;
607 } /* SRXAFSCB_TellMeAboutYourself */
610 * Routine called by the server-side callback RPC interface to
611 * obtain a unique identifier for the client. The server uses
612 * this identifier to figure out whether or not two RX connections
613 * are from the same client, and to find out which addresses go
614 * with which clients.
616 * \param[in] rxcall Ptr to the associated Rx call structure.
617 * \param[out] addr Ptr to return the list of interfaces for this client
619 * \post Returns output of TellMeAboutYourself (which
620 * should be RXGEN_SUCCESS).
623 afs_int32
624 SRXAFSCB_WhoAreYou(struct rx_call * rxcall, struct interfaceAddr * addr)
626 return SRXAFSCB_TellMeAboutYourself(rxcall, addr, NULL);
627 } /* SRXAFSCB_WhoAreYou */
630 * Routine called by the server-side callback RPC interface to
631 * implement clearing all callbacks from this host.
633 * \param[in] rxcall Ptr to the associated Rx call structure.
634 * \param[in] serverUuid Ptr to UUID
636 * \post Returns RXGEN_SUCCESS (always)
639 afs_int32
640 SRXAFSCB_InitCallBackState3(struct rx_call * rxcall, afsUUID * serverUuid)
642 struct rx_connection *rxconn = rx_ConnectionOf(rxcall);
643 struct rx_peer *rxpeer = rx_PeerOf(rxconn);
644 struct afscp_server *server = afscp_AnyServerByAddr(rx_HostOf(rxpeer));
645 struct afscp_callback *cb;
646 struct afscp_venusfid f;
647 int i;
649 if (server == NULL) {
650 return 0;
652 for (i = 0; i < afscp_maxcallbacks; i++) {
653 cb = &allcallbacks[i];
654 if (cb->server != server)
655 continue;
656 if (cb->valid) {
657 f.cell = afscp_CellById(cb->server->cell);
658 memcpy(&f.fid, &cb->fid, sizeof(struct AFSFid));
659 _StatInvalidate(&f);
661 cb->valid = 0;
663 return RXGEN_SUCCESS;
664 } /* SRXAFSCB_InitCallBackState3 */
667 * Routine called by the server-side callback RPC interface to
668 * implement ``probing'' the Cache Manager, just making sure it's
669 * still there is still the same client it used to be.
671 * \param rxcall Ptr to the associated Rx call structure.
672 * \param clientUuid Ptr to UUID that must match the client's UUID
674 * \post Returns RXGEN_SUCCESS (always)
677 afs_int32
678 SRXAFSCB_ProbeUuid(struct rx_call * rxcall, afsUUID * clientUuid)
680 int code = 0;
681 if (!afs_cb_inited)
682 init_afs_cb();
683 if (!afs_uuid_equal(clientUuid, &afs_cb_interface.uuid))
684 code = 1; /* failure */
685 return code;
686 } /* SRXAFSCB_ProbeUuid */
689 * Routine to list server preferences used by this client.
691 * \param[in] a_call Ptr to Rx call on which this request came in.
692 * \param[in] a_index Input server index
693 * \param[out] a_srvr_addr Output server address (0xffffffff on last server)
694 * \param[out] a_srvr_rank Output server rank
696 * \post Returns RXGEN_SUCCESS (always)
699 afs_int32
700 SRXAFSCB_GetServerPrefs(struct rx_call * a_call, afs_int32 a_index,
701 afs_int32 * a_srvr_addr, afs_int32 * a_srvr_rank)
703 *a_srvr_addr = 0xffffffff;
704 *a_srvr_rank = 0xffffffff;
705 return RXGEN_SUCCESS;
706 } /* SRXAFSCB_GetServerPrefs */
709 * Routine to list cells configured for this client
711 * \param[in] a_call Ptr to Rx call on which this request came in.
712 * \param[in] a_index Input cell index
713 * \param[out] a_name Output cell name ("" on last cell)
714 * \param[out] a_hosts Output cell database servers
716 * \post Returns RXGEN_OPCODE (always)
719 afs_int32
720 SRXAFSCB_GetCellServDB(struct rx_call * a_call, afs_int32 a_index,
721 char **a_name, afs_int32 * a_hosts)
723 return RXGEN_OPCODE;
724 } /* SRXAFSCB_GetCellServDB */
727 * Routine to return name of client's local cell
729 * \param[in] a_call Ptr to Rx call on which this request came in.
730 * \param[out] a_name Output cell name
732 * \post Returns RXGEN_SUCCESS (always)
736 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
738 return RXGEN_OPCODE;
739 } /* SRXAFSCB_GetLocalCell */
742 * Routine to return parameters used to initialize client cache.
743 * Client may request any format version. Server may not return
744 * format version greater than version requested by client.
746 * \param[in] a_call Ptr to Rx call on which this request came in.
747 * \param[in] callerVersion Data format version desired by the client.
748 * \param[out] serverVersion Data format version of output data.
749 * \param[out] configCount Number bytes allocated for output data.
750 * \param[out] config Client cache configuration.
752 * \post Returns RXGEN_SUCCESS (always)
756 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
757 afs_uint32 * serverVersion, afs_uint32 * configCount,
758 cacheConfig * config)
760 return RXGEN_OPCODE;
761 } /* SRXAFSCB_GetCacheConfig */
766 * \param[in] rxcall Ptr to the associated Rx call structure.
768 * \post Returns RXGEN_OPCODE (always)
772 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_index,
773 char **a_name, afs_int32 * a_hosts)
775 return RXGEN_OPCODE;
776 } /* SRXAFSCB_GetCellByNum */