util: $(DIR_roken) procmgmt hcrypto lwp_depinstall rx_depinstall
+${COMPILE_PART1} util ${COMPILE_PART2}
+libafscp: util afs volser vlserver rx auth fsint
+ +if test "@BUILD_KRB5@" = "yes"; then \
+ ${COMPILE_PART1} libafscp ${COMPILE_PART2} ; \
+ else \
+ echo Skipping libafscp for ${SYS_NAME} ; \
+ fi
+
audit: util rx rxkad fsint
+${COMPILE_PART1} audit ${COMPILE_PART2} #TODO
finale: project cmd comerr afsd butc tbutc tbudb @ENABLE_KERNEL_MODULE@ libuafs audit kauth log \
ptserver tptserver scout bu_utils ubik uss bozo @VFSCK@ volser tvolser tsalvaged \
- dviced dvolser \
+ dviced dvolser libafscp\
venus update xstat afsmonitor rxdebug libafsrpc rfc3961 hcrypto \
libafsauthent shlibafsrpc shlibafsauthent libadmin man-pages \
platform kopenafs authtools $(DIR_roken)
finale_nolibafs: project cmd comerr afsd butc tbutc tbudb libuafs audit kauth log \
ptserver tptserver scout bu_utils ubik tubik uss bozo @VFSCK@ volser tvolser tsalvaged \
- dviced dvolser \
+ dviced dvolser libafscp\
venus update xstat afsmonitor rxdebug libafsrpc rfc3961 hcrypto \
libafsauthent shlibafsrpc shlibafsauthent libadmin man-pages \
platform kopenafs authtools $(DIR_roken)
-${COMPILE_PART1} config ${COMPILE_CLEAN}
-${COMPILE_PART1} procmgmt ${COMPILE_CLEAN}
-${COMPILE_PART1} util ${COMPILE_CLEAN}
+ -${COMPILE_PART1} libafscp ${COMPILE_CLEAN}
-${COMPILE_PART1} audit ${COMPILE_CLEAN}
-${COMPILE_PART1} comerr ${COMPILE_CLEAN}
-${COMPILE_PART1} cmd ${COMPILE_CLEAN}
src/uss/Makefile \
src/util/Makefile \
src/util/test/Makefile \
+ src/libafscp/Makefile \
src/venus/Makefile \
src/venus/test/Makefile \
src/vfsck/Makefile \
[Define to 1 if you have the `krb524_convert_creds_kdc' function.])])])])
AC_CHECK_HEADERS([kerberosIV/krb.h])
AC_CHECK_HEADERS([kerberosV/heim_err.h])
- AC_CHECK_MEMBERS([krb5_creds.keyblock, krb5_creds.session,
+ AC_CHECK_MEMBERS([krb5_creds.keyblock, krb5_creds.keyblock.enctype, krb5_creds.session,
krb5_prompt.type], , , [#include <krb5.h>])
RRA_LIB_KRB5_RESTORE])
AC_SUBST([BUILD_KRB5])
src/uss/Makefile \
src/util/Makefile \
src/util/test/Makefile \
+src/libafscp/Makefile \
src/venus/Makefile \
src/venus/test/Makefile \
src/vfsck/Makefile \
--- /dev/null
+srcdir=@srcdir@
+include @TOP_OBJDIR@/src/config/Makefile.config
+include @TOP_OBJDIR@/src/config/Makefile.pthread
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+
+#for debugging:
+#CFLAGS += -DAFSCP_DEBUG
+KRB5CFLAGS = @KRB5_CPPFLAGS@
+KRB5LIBS = @KRB5_LIBS@
+
+LIBOBJS = \
+ afscp_callback.o \
+ afscp_server.o \
+ afscp_fid.o \
+ afscp_volume.o \
+ afscp_file.o \
+ afscp_dir.o \
+ afscp_init.o \
+ afscp_util.o \
+ afscp_dirops.o \
+ afscp_acl.o
+
+all: \
+ ${TOP_LIBDIR}/libafsutil.a \
+ ${TOP_LIBDIR}/libafscp.a \
+ depinstall
+
+#
+# Build targets
+#
+${TOP_LIBDIR}/libafscp.a: libafscp.a
+ ${INSTALL_DATA} $? $@
+
+libafscp.a: ${LIBOBJS} AFS_component_version_number.o
+ $(RM) -f $@
+ $(AR) crv $@ ${LIBOBJS} AFS_component_version_number.o
+ $(RANLIB) $@
+
+depinstall: \
+ ${TOP_INCDIR}/afs/afscp.h
+
+${TOP_INCDIR}/afs/afscp.h: afscp.h
+ ${INSTALL_DATA} $? $@
+
+CFLAGS_afscp_util.o = $(KRB5CFLAGS)
+CFLAGS_afscp_server.o = $(KRB5CFLAGS)
+
+#
+# Install targets
+#
+install: all
+ ${INSTALL} -d ${DESTDIR}${libdir}
+ ${INSTALL} -d ${DESTDIR}${includedir}/afs
+ ${INSTALL_DATA} libafscp.a ${DESTDIR}${libdir}/libafscp.a
+ ${INSTALL_DATA} afscp.h ${DESTDIR}${includedir}/afs/afscp.h
+
+dest: all
+ ${INSTALL} -d ${DEST}/lib
+ ${INSTALL} -d ${DEST}/include/afs
+ ${INSTALL_DATA} libafscp.a ${DEST}/lib/libafscp.a
+ ${INSTALL_DATA} afscp.h ${DEST}/include/afs/afscp.h
+
+#
+# Misc targets
+#
+clean:
+ $(RM) -f *.o *.a *.gch libafscp* core AFS_component_version_number.c
+
+include ../config/Makefile.version
-#ifndef _AFSCP_H_
-#define _AFSCP_H_
+#ifndef AFS_SRC_LIBAFSCP_AFSCP_H
+#define AFS_SRC_LIBAFSCP_AFSCP_H
/* AUTORIGHTS */
#include <afs/param.h>
#include <afs/afsint.h>
-struct afs_server;
-struct afs_cell;
-struct afs_callback ;
-
-struct afs_volume
-{
- struct afs_cell *cell;
- afs_uint32 id;
- int voltype;
- int nservers;
- int servers[16];
- char name[256];
- void *statcache;
- void *dircache;
+#include <afs/afs_consts.h>
+#include <afs/cellconfig.h>
+#include <afs/dir.h>
+#include <afs/afsutil.h>
+
+struct afscp_server {
+ afsUUID id;
+ int index;
+ int cell;
+ int naddrs;
+ afs_uint32 addrs[AFS_MAXHOSTS];
+ struct rx_connection *conns[AFS_MAXHOSTS];
};
-struct afs_venusfid
-{
- struct afs_cell *cell;
- struct AFSFid fid;
+struct afscp_cell {
+ int id;
+ char name[MAXCELLCHARS + 1];
+ struct rx_securityClass *security;
+ int scindex;
+ struct ubik_client *vlservers;
+ int nservers;
+ int srvsalloced;
+ struct afscp_server **fsservers;
+ void *volsbyname;
+ void *volsbyid;
+ char *realm;
};
-struct afs_dirent
-{
- afs_uint32 vnode;
- afs_uint32 unique;
- char name[16+32*(64-2)]; /* 64 is EPP. */
+struct afscp_volume {
+ struct afscp_cell *cell;
+ afs_uint32 id;
+ int voltype;
+ int nservers;
+ int servers[AFS_MAXHOSTS];
+ char name[AFSNAMEMAX];
+ void *statcache;
+ void *dircache;
};
-typedef struct afs_dirstream afs_DIR;
-typedef struct afs_openfile afs_FILE;
-
-extern int afs_errno;
-int afscp_init(const char *cellname);
-void afscp_finalize(void);
-
-#ifdef API_COMPAT
-#define GetCellByName afs_cellbyname
-#define GetCellById afs_cellbyid
-#define GetDefaultCell afs_defaultcell
-#define SetDefaultCell afs_setdefaultcell
-#define GetCellID afs_cellid
-#endif
-struct afs_cell *afs_defaultcell(void);
-struct afs_cell *afs_cellbyname(const char *cellname) ;
-int afs_setdefaultcell(const char *cellname);
-struct afs_cell *afs_cellbyid(int id);
-int afs_cellid(struct afs_cell *cell);
-
-
-#ifdef API_COMPAT
-#define GetServerById afs_serverbyid
-#define GetServerByAddr afs_serverbyaddr
-#define GetAnyServerById afs_anyserverbyaddr
-#define GetAnyServerByIndex afs_serverbyindex
-#define GetConnection afs_serverconnection
-#endif
-
-struct afs_server *afs_serverbyid(struct afs_cell *thecell, afsUUID *u);
-struct afs_server *afs_serverbyaddr(struct afs_cell *thecell,
- afs_uint32 addr);
-struct afs_server *afs_anyserverbyaddr(afs_uint32 addr) ;
-struct afs_server *afs_serverbyindex(int idx) ;
-struct rx_connection *afs_serverconnection(const struct afs_server *srv,
- int i);
-
-int AddCallBack(const struct afs_server *server, const struct AFSFid *fid,
- const struct AFSFetchStatus *st, const struct AFSCallBack *cb);
-int RemoveCallBack(const struct afs_server *server, const struct afs_venusfid *fid);
-int ReturnCallBacks(const struct afs_server *server);
-int ReturnAllCallBacks(void);
+struct afscp_venusfid {
+ struct afscp_cell *cell;
+ struct AFSFid fid;
+};
+
+struct afscp_dirent {
+ afs_uint32 vnode;
+ afs_uint32 unique;
+ char name[16 + 32 * (EPP - 2)];
+};
+
+struct afscp_dirstream {
+ struct afscp_venusfid fid;
+ int buflen;
+ char *dirbuffer;
+ int hashent;
+ int entry;
+ int dv;
+ struct afscp_dirent ret;
+};
+
+struct afscp_dircache {
+ struct afscp_venusfid me;
+ int buflen;
+ char *dirbuffer;
+ int dv;
+};
+
+struct afscp_statent {
+ struct afscp_venusfid me;
+ struct AFSFetchStatus status;
+};
+
+struct afscp_openfile {
+ struct afscp_venusfid fid;
+ off_t offset;
+};
+
+struct afscp_callback {
+ int valid;
+ const struct afscp_server *server;
+ struct AFSFid fid;
+ struct AFSCallBack cb;
+ time_t as_of;
+};
+extern int afscp_errno;
+int afscp_Init(const char *);
+void afscp_Finalize(void);
+
+int afscp_Insecure(void);
+int afscp_AnonymousAuth(int);
+
+struct afscp_cell *afscp_DefaultCell(void);
+struct afscp_cell *afscp_CellByName(const char *, const char *);
+int afscp_SetDefaultRealm(const char *);
+int afscp_SetDefaultCell(const char *);
+struct afscp_cell *afscp_CellById(int);
+int afscp_CellId(struct afscp_cell *);
+void afscp_FreeAllCells(void);
+void afscp_FreeAllServers(void);
+
+struct afscp_server *afscp_ServerById(struct afscp_cell *, afsUUID *);
+struct afscp_server *afscp_ServerByAddr(struct afscp_cell *, afs_uint32);
+struct afscp_server *afscp_AnyServerByAddr(afs_uint32);
+struct afscp_server *afscp_ServerByIndex(int);
+struct rx_connection *afscp_ServerConnection(const struct afscp_server *,
+ int);
+
+int afscp_AddCallBack(const struct afscp_server *,
+ const struct AFSFid *,
+ const struct AFSFetchStatus *,
+ const struct AFSCallBack *, const time_t);
+int afscp_RemoveCallBack(const struct afscp_server *,
+ const struct afscp_venusfid *);
+int afscp_ReturnCallBacks(const struct afscp_server *);
+int afscp_ReturnAllCallBacks(void);
/* file metastuff */
/* frees with free() */
-struct afs_venusfid *makefid(struct afs_cell *cell, afs_uint32 volume,
- afs_uint32 vnode, afs_uint32 unique);
-struct afs_venusfid *dupfid(const struct afs_venusfid *in);
+struct afscp_venusfid *afscp_MakeFid(struct afscp_cell *, afs_uint32,
+ afs_uint32, afs_uint32);
+struct afscp_venusfid *afscp_DupFid(const struct afscp_venusfid *);
+void afscp_FreeFid(struct afscp_venusfid *);
struct stat;
-int afs_stat(const struct afs_venusfid *fid, struct stat *s);
-
-ssize_t afs_pread(const struct afs_venusfid *fid, void *buffer, size_t count, off_t offset);
-ssize_t afs_pwrite(const struct afs_venusfid *fid, const void *buffer, size_t count, off_t offset);
-afs_FILE *afs_open(const char *path);
-afs_FILE *afs_fidopen(const struct afs_venusfid *fid);
-off_t afs_fseek (afs_FILE *f, off_t o, int whence);
-ssize_t afs_fread(const afs_FILE *f, void *buffer, size_t count);
-ssize_t afs_fwrite(const afs_FILE *f, const void *buffer, size_t count);
+int afscp_Stat(const struct afscp_venusfid *, struct stat *);
+
+ssize_t afscp_PRead(const struct afscp_venusfid *, void *, size_t, off_t);
+ssize_t afscp_PWrite(const struct afscp_venusfid *, const void *,
+ size_t, off_t);
+/*
+ * for future implementation: (?)
+ * struct afscp_openfile *afscp_FidOpen(const struct afscp_venusfid *);
+ * off_t afscp_FSeek(struct afscp_openfile *, off_t, int);
+ * ssize_t afscp_FRead(const struct afscp_openfile *, void *, size_t);
+ */
/* rpc wrappers */
-int afs_GetStatus(const struct afs_venusfid *fid, struct AFSFetchStatus *s);
-int afs_StoreStatus(const struct afs_venusfid *fid, struct AFSStoreStatus *s);
-int afs_CreateFile(const struct afs_venusfid *fid, /* const */ char *name,
- struct AFSStoreStatus *sst,
- struct afs_venusfid **ret);
-int afs_MakeDir(const struct afs_venusfid *fid, /* const */ char *name,
- struct AFSStoreStatus *sst,
- struct afs_venusfid **ret);
-int afs_Symlink(const struct afs_venusfid *fid, /* const */ char *name,
- /*const*/ char *target, struct AFSStoreStatus *sst);
-int afs_RemoveFile(const struct afs_venusfid *dir, char *name);
-int afs_RemoveDir(const struct afs_venusfid *dir, char *name);
-int afs_FetchACL(const struct afs_venusfid *dir,
- struct AFSOpaque *acl);
-int afs_StoreACL(const struct afs_venusfid *dir,
- struct AFSOpaque *acl);
+int afscp_GetStatus(const struct afscp_venusfid *, struct AFSFetchStatus *);
+int afscp_StoreStatus(const struct afscp_venusfid *, struct AFSStoreStatus *);
+int afscp_CreateFile(const struct afscp_venusfid *, char *,
+ struct AFSStoreStatus *, struct afscp_venusfid **);
+int afscp_MakeDir(const struct afscp_venusfid *, char *,
+ struct AFSStoreStatus *, struct afscp_venusfid **);
+int afscp_Symlink(const struct afscp_venusfid *, char *,
+ char *, struct AFSStoreStatus *);
+int afscp_RemoveFile(const struct afscp_venusfid *, char *);
+int afscp_RemoveDir(const struct afscp_venusfid *, char *);
+int afscp_FetchACL(const struct afscp_venusfid *, struct AFSOpaque *);
+int afscp_StoreACL(const struct afscp_venusfid *, struct AFSOpaque *);
+
/* directory parsing stuff*/
-struct afs_dirstream *afs_opendir(const struct afs_venusfid *fid);
-struct afs_dirent *afs_readdir(struct afs_dirstream *d);
-int afs_rewinddir(struct afs_dirstream *d);
-int afs_closedir(struct afs_dirstream *d);
-struct afs_venusfid *DirLookup(struct afs_dirstream *d, const char *name);
-struct afs_venusfid *ResolveName(const struct afs_venusfid *dir, const char *name);
-struct afs_venusfid *ResolvePath(const char *path);
-struct afs_venusfid *ResolvePath2(const struct afs_volume *start, const char *path);
+struct afscp_dirstream *afscp_OpenDir(const struct afscp_venusfid *);
+struct afscp_dirent *afscp_ReadDir(struct afscp_dirstream *);
+int afscp_RewindDir(struct afscp_dirstream *);
+int afscp_CloseDir(struct afscp_dirstream *);
+struct afscp_venusfid *afscp_DirLookup(struct afscp_dirstream *,
+ const char *);
+struct afscp_venusfid *afscp_ResolveName(const struct afscp_venusfid *,
+ const char *);
+struct afscp_venusfid *afscp_ResolvePath(const char *);
+struct afscp_venusfid *afscp_ResolvePathFromVol(const struct afscp_volume *,
+ const char *);
/* vldb stuff */
-struct afs_volume *afs_volumebyname(struct afs_cell *cell, const char *vname, afs_int32 vtype);
-struct afs_volume *afs_volumebyid(struct afs_cell *cell, afs_uint32 id);
-
-#define DIRMODE_CELL 0
-#define DIRMODE_DYNROOT 1
+struct afscp_volume *afscp_VolumeByName(struct afscp_cell *,
+ const char *, afs_int32);
+struct afscp_volume *afscp_VolumeById(struct afscp_cell *, afs_uint32);
-#define VOLTYPE_RW 0
-#define VOLTYPE_RO 1
-#define VOLTYPE_BK 2
-int SetDirMode(int mode);
+#define DIRMODE_CELL 0
+#define DIRMODE_DYNROOT 1
+int afscp_SetDirMode(int);
-#endif
+#endif /* AFS_SRC_LIBAFSCP_AFSCP_H */
(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>
+
+#include <roken.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
#include <afs/dir.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
#include "afscp.h"
#include "afscp_internal.h"
+int
+afscp_FetchACL(const struct afscp_venusfid *dir, struct AFSOpaque *acl)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst;
+ struct AFSVolSync vs;
+ struct afscp_server *server;
-int afs_FetchACL(const struct afs_venusfid *dir,
- struct AFSOpaque *acl) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst;
- struct AFSVolSync vs;
- struct afs_volume *volume;
- struct afs_server *server;
-
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_FetchACL(server->conns[j], &df, acl, &dfst, &vs);
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ code = RXAFS_FetchACL(server->conns[j], &df, acl, &dfst, &vs);
+ if (code >= 0)
+ break;
+ }
+ }
if (code >= 0)
- break;
- }
+ break;
}
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- return 0;
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
+ }
+ _StatStuff(dir, &dfst);
+ return 0;
}
-int afs_StoreACL(const struct afs_venusfid *dir,
- struct AFSOpaque *acl) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst;
- struct AFSVolSync vs;
- struct afs_volume *volume;
- struct afs_server *server;
+int
+afscp_StoreACL(const struct afscp_venusfid *dir, struct AFSOpaque *acl)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst;
+ struct AFSVolSync vs;
+ struct afscp_server *server;
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_StoreACL(server->conns[j], &df, acl, &dfst, &vs);
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ code = RXAFS_StoreACL(server->conns[j], &df, acl, &dfst, &vs);
+ if (code >= 0)
+ break;
+ }
+ }
if (code >= 0)
- break;
- }
+ break;
+ }
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
}
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- return 0;
+ _StatStuff(dir, &dfst);
+ return 0;
}
(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 */
(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>
+
+#include <roken.h>
+
+#include <search.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
#include <afs/dir.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <search.h>
#include "afscp.h"
#include "afscp_internal.h"
-static int dirmode=DIRMODE_CELL;
+static int dirmode = DIRMODE_CELL;
-int SetDirMode(int mode) {
-
- if (mode != DIRMODE_CELL && mode != DIRMODE_DYNROOT) {
- afs_errno=EINVAL;
- return -1;
- }
- dirmode=mode;
- return 0;
+int
+afscp_SetDirMode(int mode)
+{
+ if ((mode != DIRMODE_CELL) && (mode != DIRMODE_DYNROOT)) {
+ afscp_errno = EINVAL;
+ return -1;
+ }
+ dirmode = mode;
+ return 0;
}
/* comparison function for tsearch */
-static int dircompare(const void *a, const void *b)
+static int
+dircompare(const void *a, const void *b)
{
- const struct afs_dircache *sa=a,*sb=b;
- if (sa->me.fid.Vnode < sb->me.fid.Vnode) return -1;
- if (sa->me.fid.Vnode > sb->me.fid.Vnode) return 1;
- if (sa->me.fid.Unique < sb->me.fid.Unique) return -1;
- if (sa->me.fid.Unique > sb->me.fid.Unique) return 1;
- return 0;
+ const struct afscp_dircache *sa = a, *sb = b;
+ if (sa->me.fid.Vnode < sb->me.fid.Vnode)
+ return -1;
+ if (sa->me.fid.Vnode > sb->me.fid.Vnode)
+ return 1;
+ if (sa->me.fid.Unique < sb->me.fid.Unique)
+ return -1;
+ if (sa->me.fid.Unique > sb->me.fid.Unique)
+ return 1;
+ return 0;
}
/* make sure the dirstream contains the most up to date directory contents */
-static int _DirUpdate (struct afs_dirstream *d) {
- struct AFSFetchStatus s;
- int code;
- struct afs_volume *v;
- struct afs_dircache key, *stored;
- void **cached;
-
-
- code=afs_GetStatus(&d->fid, &s);
- if (code)
- return code;
-
- if (d->dirbuffer && d->dv == s.DataVersion)
- return 0;
- v=afs_volumebyid(d->fid.cell, d->fid.fid.Volume);
- if (!v) {
- afs_errno=ENOENT;
- return -1;
- }
-
- memcpy(&key.me, &d->fid, sizeof(struct afs_venusfid));
- cached=tfind(&key, &v->dircache, dircompare);
- if (cached) {
- stored=*(struct afs_dircache **)cached;
- if (d->dv == s.DataVersion) {
- d->dirbuffer = stored->dirbuffer;
- d->buflen = stored->buflen;
- d->dv = stored->dv;
- return 0;
- }
- tdelete(&key, &v->dircache, dircompare);
- if (d->dirbuffer != stored->dirbuffer)
- free(stored->dirbuffer);
- free(stored);
- }
- if (s.Length > BIGMAXPAGES * AFS_PAGESIZE) {
- afs_errno=EFBIG;
- return -1;
- }
- if (d->buflen != s.Length) {
- char *new;
- if (d->dirbuffer) {
- new=realloc(d->dirbuffer, s.Length);
- } else {
- new=malloc(s.Length);
- }
- if (new) {
- d->dirbuffer=new;
- } else {
- afs_errno=ENOMEM;
- return -1;
- }
- d->buflen=s.Length;
- }
-
- code=afs_pread(&d->fid, d->dirbuffer, s.Length, 0);
- if (code < 0) {
- return -1;
- }
- d->dv=s.DataVersion;
- cached=tsearch(&key, &v->dircache, dircompare);
- if (cached) {
- stored=malloc(sizeof(struct afs_dircache));
- if (stored) {
- memcpy(&stored->me, &d->fid, sizeof(struct afs_venusfid));
- stored->buflen=d->buflen;
- stored->dirbuffer=d->dirbuffer;
- stored->dv=d->dv;
- *(struct afs_dircache **)cached=stored;
- } else {
- tdelete(&key, &v->dircache, dircompare);
- }
- }
- return 0;
+static int
+_DirUpdate(struct afscp_dirstream *d)
+{
+ struct AFSFetchStatus s;
+ int code;
+ struct afscp_volume *v;
+ struct afscp_dircache key, *stored;
+ void **cached;
+
+
+ code = afscp_GetStatus(&d->fid, &s);
+ if (code != 0) {
+ return code;
+ }
+
+ if (d->dirbuffer && d->dv == s.DataVersion) {
+ return 0;
+ }
+ v = afscp_VolumeById(d->fid.cell, d->fid.fid.Volume);
+ if (v == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+
+ memcpy(&key.me, &d->fid, sizeof(struct afscp_venusfid));
+ cached = tfind(&key, &v->dircache, dircompare);
+ if (cached != NULL) {
+ stored = *(struct afscp_dircache **)cached;
+ if (d->dv == s.DataVersion) {
+ d->dirbuffer = stored->dirbuffer;
+ d->buflen = stored->buflen;
+ d->dv = stored->dv;
+ return 0;
+ }
+ tdelete(&key, &v->dircache, dircompare);
+ if (d->dirbuffer != stored->dirbuffer)
+ free(stored->dirbuffer);
+ free(stored);
+ }
+ if (s.Length > BIGMAXPAGES * AFS_PAGESIZE) {
+ afscp_errno = EFBIG;
+ return -1;
+ }
+ if (d->buflen != s.Length) {
+ char *new;
+ if (d->dirbuffer) {
+ new = realloc(d->dirbuffer, s.Length);
+ } else {
+ new = malloc(s.Length);
+ }
+ if (new != NULL) {
+ d->dirbuffer = new;
+ } else {
+ afscp_errno = ENOMEM;
+ return -1;
+ }
+ d->buflen = s.Length;
+ }
+
+ code = afscp_PRead(&d->fid, d->dirbuffer, s.Length, 0);
+ if (code < 0) {
+ return -1;
+ }
+ d->dv = s.DataVersion;
+ cached = tsearch(&key, &v->dircache, dircompare);
+ if (cached != NULL) {
+ stored = malloc(sizeof(struct afscp_dircache));
+ if (stored != NULL) {
+ memcpy(&stored->me, &d->fid, sizeof(struct afscp_venusfid));
+ stored->buflen = d->buflen;
+ stored->dirbuffer = d->dirbuffer;
+ stored->dv = d->dv;
+ *(struct afscp_dircache **)cached = stored;
+ } else {
+ tdelete(&key, &v->dircache, dircompare);
+ }
+ }
+ return 0;
}
-
-static struct DirEntry *dir_get_entry(struct afs_dirstream *d, int entry) {
-
- struct DirHeader *h=(struct DirHeader *)d->dirbuffer;
- struct PageHeader *p;
- struct DirEntry *ret;
- int fr;
- int pg, off;
-
-
- pg=entry >> LEPP;
- off=entry & (EPP-1);
-
- if (pg * AFS_PAGESIZE >= d->buflen) { /* beyond end of file */
- return NULL;
- }
- if (!off || (!pg && off < DHE + 1)) { /* offset refers to metadata */
- return NULL;
- }
- if (pg < MAXPAGES && h->alloMap[pg] == EPP) { /* page is empty */
- return NULL;
- }
- p=(struct PageHeader *)&d->dirbuffer[pg * AFS_PAGESIZE];
- fr=p->freebitmap[off >> 8];
-#if 0
- if ((fr & (1<<(off & 7))) == 0 ) { /* entry isn't allocated */
- return NULL;
- }
-#endif
-
- ret=(struct DirEntry *)&d->dirbuffer[pg * AFS_PAGESIZE + 32 * off];
-
- return ret;
+static struct DirEntry *
+dir_get_entry(struct afscp_dirstream *d, int entry)
+{
+ struct DirHeader *h = (struct DirHeader *)d->dirbuffer;
+ /* struct PageHeader *p; */
+ struct DirEntry *ret;
+ /* int fr; */
+ int pg, off;
+
+ pg = entry >> LEPP;
+ off = entry & (EPP - 1);
+
+ if (pg * AFS_PAGESIZE >= d->buflen) { /* beyond end of file */
+ return NULL;
+ }
+ if (!off || (!pg && off < DHE + 1)) { /* offset refers to metadata */
+ return NULL;
+ }
+ if (pg < MAXPAGES && h->alloMap[pg] == EPP) { /* page is empty */
+ return NULL;
+ }
+ /* p = (struct PageHeader *)&d->dirbuffer[pg * AFS_PAGESIZE]; */
+ /* p is set but not referenced later */
+ /* fr = p->freebitmap[off >> 8]; */
+ /* fr is set but not referenced later */
+ ret = (struct DirEntry *)&d->dirbuffer[pg * AFS_PAGESIZE + 32 * off];
+ return ret;
}
-struct afs_dirstream *afs_opendir(const struct afs_venusfid *fid) {
- struct afs_dirstream *ret;
- struct AFSFetchStatus s;
- int code;
-
- code=afs_GetStatus(fid, &s);
- if (code) {
- return NULL;
- }
-
- if (s.FileType != Directory) {
- afs_errno=ENOTDIR;
- return NULL;
- }
- ret=malloc(sizeof(struct afs_dirstream));
- if (!ret) {
- afs_errno=ENOMEM;
- return NULL;
- }
- memset(ret,0,sizeof(struct afs_dirstream));
- memmove(&ret->fid, fid, sizeof(struct afs_venusfid));
- code=_DirUpdate(ret);
- if (code < 0) {
- afs_closedir(ret);
- return NULL;
- }
- ret->hashent=-1;
- ret->entry=0;
- return ret;
+struct afscp_dirstream *
+afscp_OpenDir(const struct afscp_venusfid *fid)
+{
+ struct afscp_dirstream *ret;
+ struct AFSFetchStatus s;
+ int code;
+
+ code = afscp_GetStatus(fid, &s);
+ if (code != 0) {
+ return NULL;
+ }
+
+ if (s.FileType != Directory) {
+ afscp_errno = ENOTDIR;
+ return NULL;
+ }
+ ret = malloc(sizeof(struct afscp_dirstream));
+ if (ret == NULL) {
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ memset(ret, 0, sizeof(struct afscp_dirstream));
+ memmove(&ret->fid, fid, sizeof(struct afscp_venusfid));
+ code = _DirUpdate(ret);
+ if (code < 0) {
+ afscp_CloseDir(ret);
+ return NULL;
+ }
+ ret->hashent = -1;
+ ret->entry = 0;
+
+ return ret;
}
-struct afs_dirent *afs_readdir(struct afs_dirstream *d) {
- struct DirHeader *h=(struct DirHeader *)d->dirbuffer;
- struct DirEntry *info;
- int ent;
-
-
- ent=d->entry;
- while (ent == 0 && d->hashent < NHASHENT-1) {
- d->hashent++;
- ent=ntohs(h->hashTable[d->hashent]);
- }
- if (ent == 0) {
- afs_errno=0;
- return NULL;
- }
- info=dir_get_entry(d, ent);
- if (!info) {
- afs_errno=0;
- return NULL;
- }
- d->ret.vnode=ntohl(info->fid.vnode);
- d->ret.unique=ntohl(info->fid.vunique);
- strcpy(d->ret.name, info->name); /* guaranteed to be NULL terminated? */
- d->entry=ntohs(info->next);
-
- return &d->ret;
+struct afscp_dirent *
+afscp_ReadDir(struct afscp_dirstream *d)
+{
+ struct DirHeader *h = (struct DirHeader *)d->dirbuffer;
+ struct DirEntry *info;
+ int ent;
+
+
+ ent = d->entry;
+ while (ent == 0 && d->hashent < NHASHENT - 1) {
+ d->hashent++;
+ ent = ntohs(h->hashTable[d->hashent]);
+ }
+ if (ent == 0) {
+ afscp_errno = 0;
+ return NULL;
+ }
+ info = dir_get_entry(d, ent);
+ if (info == NULL) {
+ afscp_errno = 0;
+ return NULL;
+ }
+ d->ret.vnode = ntohl(info->fid.vnode);
+ d->ret.unique = ntohl(info->fid.vunique);
+ strlcpy(d->ret.name, info->name, sizeof(d->ret.name)); /* guaranteed to be NULL terminated? */
+ d->entry = ntohs(info->next);
+
+ return &d->ret;
}
/* as it calls _DirUpdate, this may corrupt any previously returned dirent's */
-int afs_rewinddir(struct afs_dirstream *d) {
- _DirUpdate(d);
- d->hashent=-1;
- d->entry=0;
- return 0;
-}
-int afs_closedir(struct afs_dirstream *d) {
- free(d);
- return 0;
+int
+afscp_RewindDir(struct afscp_dirstream *d)
+{
+ _DirUpdate(d);
+ d->hashent = -1;
+ d->entry = 0;
+ return 0;
}
-static int namehash(const char *name)
+int
+afscp_CloseDir(struct afscp_dirstream *d)
{
- int hval, tval;
-
- hval=0;
- while (*name) hval = (hval * 173) + *name++;
- tval = hval & (NHASHENT - 1);
- return tval ?
- (hval < 0 ? NHASHENT - tval : tval)
- : 0;
+ free(d);
+ return 0;
}
-
-struct afs_venusfid *DirLookup(struct afs_dirstream *d, const char *name) {
- int fid[3];
- int code;
- int hval, entry;
- struct DirHeader *h=(struct DirHeader *)d->dirbuffer;
- struct DirEntry *info;
-
- code=_DirUpdate(d);
- if (code)
- return NULL;
- hval=namehash(name);
- entry=ntohs(h->hashTable[hval]);
-
- while (entry) {
- info=dir_get_entry(d, entry);
- if (!info) {
- afs_errno=EIO;
- return NULL;
- }
- if (!strcmp(info->name, name))
- break;
- entry=ntohs(info->next);
- }
- if (entry) {
- return makefid(d->fid.cell, d->fid.fid.Volume,
- ntohl(info->fid.vnode),
- ntohl(info->fid.vunique));
- } else {
- afs_errno=ENOENT;
- return NULL;
- }
+static int
+namehash(const char *name)
+{
+ int hval, tval;
+
+ hval = 0;
+ while (*name != '\0')
+ hval = (hval * 173) + *name++;
+ tval = hval & (NHASHENT - 1);
+ return tval ? (hval < 0 ? NHASHENT - tval : tval)
+ : 0;
}
-struct afs_venusfid *ResolveName(const struct afs_venusfid *dir, const char *name) {
- struct afs_venusfid *ret;
- struct afs_dirstream *d;
+struct afscp_venusfid *
+afscp_DirLookup(struct afscp_dirstream *d, const char *name)
+{
+ int code;
+ int hval, entry;
+ struct DirHeader *h = (struct DirHeader *)d->dirbuffer;
+ struct DirEntry *info;
+
+ code = _DirUpdate(d);
+ if (code != 0) {
+ return NULL;
+ }
+ hval = namehash(name);
+ entry = ntohs(h->hashTable[hval]);
+
+ while (entry != 0) {
+ info = dir_get_entry(d, entry);
+ if (info == NULL) {
+ afscp_errno = EIO;
+ return NULL;
+ }
+ if (strcmp(info->name, name) == 0)
+ break;
+ entry = ntohs(info->next);
+ }
+ if (entry != 0) {
+ return afscp_MakeFid(d->fid.cell, d->fid.fid.Volume,
+ ntohl(info->fid.vnode),
+ ntohl(info->fid.vunique));
+ } else {
+ afscp_errno = ENOENT;
+ return NULL;
+ }
+}
- d=afs_opendir(dir);
- if (!d)
- return NULL;
- ret=DirLookup(d, name);
- afs_closedir(d);
- return ret;
+struct afscp_venusfid *
+afscp_ResolveName(const struct afscp_venusfid *dir, const char *name)
+{
+ struct afscp_venusfid *ret;
+ struct afscp_dirstream *d;
+
+ d = afscp_OpenDir(dir);
+ if (d == NULL) {
+ return NULL;
+ }
+ ret = afscp_DirLookup(d, name);
+ afscp_CloseDir(d);
+ return ret;
}
-static int gettoproot(struct afs_cell *cell, char *p, char **q, struct afs_venusfid **root) {
- struct afs_volume *rootvol;
- char *r;
-
- if (dirmode == DIRMODE_DYNROOT && !strcmp(p, "/afs")) {
- afs_errno=EINVAL;
- return 1;
- }
- if (!strncmp(p,"/afs",4)) {
- afscp_dprintf(("gettoproot: path is absolute\n"));
- p=&p[5];
- while (*p == '/') p++;
- if (dirmode == DIRMODE_DYNROOT) {
- int voltype;
+static int
+gettoproot(struct afscp_cell *cell, char *p, char **q,
+ struct afscp_venusfid **root)
+{
+ struct afscp_volume *rootvol;
+ char *r;
+
+ if (dirmode == DIRMODE_DYNROOT && (strcmp(p, "/afs") == 0)) {
+ afscp_errno = EINVAL;
+ return 1;
+ }
+ if (strncmp(p, "/afs", 4) == 0) {
+ afs_dprintf(("gettoproot: path is absolute\n"));
+ p = &p[5];
+ while (*p == '/')
+ p++;
+ if (dirmode == DIRMODE_DYNROOT) {
+ int voltype;
retry_dot:
- voltype = VOLTYPE_RO;
- if (*p == '.') {
- p++;
- voltype=VOLTYPE_RW;
- }
- if (*p == '/') {
- while (*p == '/') p++;
- goto retry_dot;
- }
- if (*p == '.' || *p == 0) {
- afs_errno=EINVAL;
- return 1;
- }
- r=p;
- while (*r && *r != '/') r++;
- if (!*r) {
- afs_errno=ENODEV;
- return 1;
- }
- *r++=0;
- *q=r;
- afscp_dprintf(("gettoproot: dynroot looking up cell %s\n", p));
- cell=afs_cellbyname(p);
- if (!cell) {
- afscp_dprintf(("gettoproot: no such cell\n"));
- afs_errno=ENODEV;
- return 1;
- }
- rootvol=afs_volumebyname(cell, "root.cell", voltype);
- if (!rootvol && voltype == VOLTYPE_RO)
- rootvol=afs_volumebyname(cell, "root.cell", VOLTYPE_RW);
- } else {
- *q=p;
- rootvol=afs_volumebyname(cell, "root.afs", VOLTYPE_RO);
- if (!rootvol)
- rootvol=afs_volumebyname(cell, "root.afs", VOLTYPE_RW);
- }
- if (!rootvol)
- afscp_dprintf(("gettoproot: volume not found\n"));
- } else {
- afscp_dprintf(("gettoproot: path is relative\n"));
- if (p[0] == '/') {
- afs_errno=EXDEV;
- return 1;
- }
- rootvol=afs_volumebyname(cell, "root.cell", VOLTYPE_RO);
- if (!rootvol)
- rootvol=afs_volumebyname(cell, "root.cell", VOLTYPE_RW);
- *q=p;
- }
- if (!rootvol) { afs_errno=ENODEV; return 1;}
- *root=makefid(cell, rootvol->id, 1, 1);
- return 0;
+ voltype = ROVOL;
+ if (*p == '.') {
+ p++;
+ voltype = RWVOL;
+ }
+ if (*p == '/') {
+ while (*p == '/')
+ p++;
+ goto retry_dot;
+ }
+ if (*p == '.' || *p == 0) {
+ afscp_errno = EINVAL;
+ return 1;
+ }
+ r = p;
+ while (*r && *r != '/')
+ r++;
+ if (!*r) {
+ afscp_errno = ENODEV;
+ return 1;
+ }
+ *r++ = 0;
+ *q = r;
+ afs_dprintf(("gettoproot: dynroot looking up cell %s\n", p));
+ cell = afscp_CellByName(p, NULL);
+ if (cell == NULL) {
+ afs_dprintf(("gettoproot: no such cell\n"));
+ afscp_errno = ENODEV;
+ return 1;
+ }
+ rootvol = afscp_VolumeByName(cell, "root.cell", voltype);
+ if (!rootvol && voltype == ROVOL)
+ rootvol = afscp_VolumeByName(cell, "root.cell", RWVOL);
+ } else {
+ *q = p;
+ rootvol = afscp_VolumeByName(cell, "root.afs", ROVOL);
+ if (!rootvol)
+ rootvol = afscp_VolumeByName(cell, "root.afs", RWVOL);
+ }
+ if (!rootvol)
+ afs_dprintf(("gettoproot: volume not found\n"));
+ } else {
+ afs_dprintf(("gettoproot: path is relative\n"));
+ if (p[0] == '/') {
+ afscp_errno = EXDEV;
+ return 1;
+ }
+ rootvol = afscp_VolumeByName(cell, "root.cell", ROVOL);
+ if (!rootvol)
+ rootvol = afscp_VolumeByName(cell, "root.cell", RWVOL);
+ *q = p;
+ }
+ if (rootvol == NULL) {
+ afscp_errno = ENODEV;
+ return 1;
+ }
+ *root = afscp_MakeFid(cell, rootvol->id, 1, 1);
+ return 0;
}
-static int getvolumeroot(struct afs_cell *cell, int voltype, const char *vname, struct afs_venusfid **root) {
- struct afs_volume *vol;
- vol=afs_volumebyname(cell, vname, voltype);
- if (!vol && voltype == VOLTYPE_RO)
- vol=afs_volumebyname(cell, vname, VOLTYPE_RW);
- if (!vol) { afs_errno=ENODEV; return 1;}
- *root=makefid(cell, vol->id, 1, 1);
- return 0;
+static int
+getvolumeroot(struct afscp_cell *cell, int voltype, const char *vname,
+ struct afscp_venusfid **root)
+{
+ struct afscp_volume *vol;
+ vol = afscp_VolumeByName(cell, vname, voltype);
+ if (!vol && voltype == ROVOL)
+ vol = afscp_VolumeByName(cell, vname, RWVOL);
+ if (vol == NULL) {
+ afscp_errno = ENODEV;
+ return 1;
+ }
+ *root = afscp_MakeFid(cell, vol->id, 1, 1);
+ return 0;
}
-typedef struct fidstack_s
-{
- int alloc;
- int count;
- struct afs_venusfid ** entries;
+typedef struct fidstack_s {
+ int alloc;
+ int count;
+ struct afscp_venusfid **entries;
} *fidstack;
-static fidstack fidstack_alloc() {
- fidstack ret;
-
- ret=malloc(sizeof(struct fidstack_s));
- if (!ret) {
- afs_errno=ENOMEM;
- return NULL;
- }
- ret->alloc=10;
- ret->count=0;
- ret->entries=malloc(ret->alloc * sizeof(struct afs_venusfid *));
- if (!ret->entries) {
- free(ret);
- afs_errno=ENOMEM;
- return NULL;
- }
- return ret;
+static fidstack
+fidstack_alloc(void)
+{
+ fidstack ret;
+
+ ret = malloc(sizeof(struct fidstack_s));
+ if (ret == NULL) {
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ ret->alloc = 10;
+ ret->count = 0;
+ ret->entries = malloc(ret->alloc * sizeof(struct afscp_venusfid *));
+ if (ret->entries == NULL) {
+ free(ret);
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ return ret;
}
-static void fidstack_push(fidstack s, struct afs_venusfid *entry) {
- struct afs_venusfid **new;
- if (s->count >= s->alloc) {
- new=realloc(s->entries, (s->alloc + 10) *
- sizeof(struct afs_venusfid *));
- if (!new)
- return;
- s->entries=new;
- s->alloc += 10;
- }
- s->entries[s->count++]=entry;
- return;
+static void
+fidstack_push(fidstack s, struct afscp_venusfid *entry)
+{
+ struct afscp_venusfid **new;
+ if (s->count >= s->alloc) {
+ new = realloc(s->entries, (s->alloc + 10) *
+ sizeof(struct afscp_venusfid *));
+ if (new == NULL) {
+ return;
+ }
+ s->entries = new;
+ s->alloc += 10;
+ }
+ s->entries[s->count++] = entry;
+ return;
}
-static struct afs_venusfid *fidstack_pop(fidstack s) {
- if (s->count)
- return s->entries[-- s->count];
- return NULL;
+static struct afscp_venusfid *
+fidstack_pop(fidstack s)
+{
+ if (s->count)
+ return s->entries[--s->count];
+ return NULL;
}
-static void fidstack_free(fidstack s) {
- int i;
+static void
+fidstack_free(fidstack s)
+{
+ int i;
- for (i=0;i<s->count;i++)
- free(s->entries[i]);
- free (s->entries);
- free(s);
+ for (i = 0; i < s->count; i++)
+ free(s->entries[i]);
+ free(s->entries);
+ free(s);
}
-static struct afs_venusfid *_ResolvePath(const struct afs_venusfid *, fidstack, char *, int);
-
-static struct afs_venusfid *HandleLink(struct afs_venusfid *in, const struct afs_venusfid *parent, fidstack fids, int follow,
- const struct AFSFetchStatus *s, int terminal) {
- char *linkbuf, *linkbufq;
- struct afs_cell *cell;
- struct afs_volume *v;
- struct afs_venusfid *root,*ret;
- int voltype;
- int code;
- if ((s->UnixModeBits & 0111) &&
- (follow == 0) &&
- terminal) { /* normal link */
- return in;
- }
- linkbuf=malloc(s->Length + 1);
- code=afs_pread(in, linkbuf, s->Length, 0);
- if (code < 0) {
- free(linkbuf);
- free(in);
- return NULL;
- }
- if (code != s->Length) {
- afs_errno=EIO;
- free(linkbuf);
- free(in);
- return NULL;
- }
- linkbuf[s->Length]=0;
- if (s->UnixModeBits & 0111) { /* normal link */
- afscp_dprintf(("Recursing on symlink %s...\n", linkbuf));
- if (linkbuf[0] == '/') {
- if (gettoproot(in->cell, linkbuf, &linkbufq, &root)) {
- free(linkbuf);
- free(in);
- return NULL;
- }
- free(in);
- ret=_ResolvePath(root, 0, linkbufq, 0);
- free(root);
- } else {
- free(in);
- ret=_ResolvePath(parent, fids, linkbuf, 0);
- }
-
- free(linkbuf);
-
- } else { /* mountpoint */
- afscp_dprintf(("EvalMountPoint %s...\n", linkbuf));
- linkbufq=strchr(linkbuf, ':');
- cell=in->cell;
- v=afs_volumebyid(cell, in->fid.Volume);
- free(in);
- if (!v) {
- free(linkbuf);
- afs_errno=ENODEV;
- return NULL;
- }
- voltype=v->voltype;
- if (linkbuf[0] == '%')
- voltype=VOLTYPE_RW;
- if (!linkbufq) {
- linkbufq=linkbuf+1;
- } else {
- *linkbufq++ = 0;
- cell=afs_cellbyname(linkbuf+1);
- if (linkbuf[0] != '%')
- voltype=VOLTYPE_RO;
- }
- if (!cell) {
- free(linkbuf);
- afs_errno=ENODEV;
- return NULL;
- }
- if (strlen(linkbufq) < 2) {
- free(linkbuf);
- afs_errno=ENODEV;
- return NULL;
- }
- linkbufq[strlen(linkbufq)-1]=0; /* eliminate trailer */
- if (getvolumeroot(cell, voltype, linkbufq, &ret)) {
- free(linkbuf);
- return NULL;
- }
- free(linkbuf);
- }
- return ret;
+static struct afscp_venusfid *_ResolvePath(const struct afscp_venusfid *,
+ fidstack, char *, int);
+
+static struct afscp_venusfid *
+afscp_HandleLink(struct afscp_venusfid *in,
+ const struct afscp_venusfid *parent, fidstack fids,
+ int follow, const struct AFSFetchStatus *s, int terminal)
+{
+ char *linkbuf, *linkbufq;
+ struct afscp_cell *cell;
+ struct afscp_volume *v;
+ struct afscp_venusfid *root, *ret;
+ int voltype;
+ int code;
+ ssize_t len;
+ if ((s->UnixModeBits & 0111) && (follow == 0) && terminal) { /* normal link */
+ return in;
+ }
+ linkbuf = malloc(s->Length + 1);
+ code = afscp_PRead(in, linkbuf, s->Length, 0);
+ if (code < 0) {
+ free(linkbuf);
+ free(in);
+ return NULL;
+ }
+ if (code != s->Length) {
+ afscp_errno = EIO;
+ free(linkbuf);
+ free(in);
+ return NULL;
+ }
+ linkbuf[s->Length] = 0;
+ if (s->UnixModeBits & 0111) { /* normal link */
+ afs_dprintf(("Recursing on symlink %s...\n", linkbuf));
+ if (linkbuf[0] == '/') {
+ if (gettoproot(in->cell, linkbuf, &linkbufq, &root)) {
+ free(linkbuf);
+ free(in);
+ return NULL;
+ }
+ free(in);
+ ret = _ResolvePath(root, 0, linkbufq, 0);
+ free(root);
+ } else {
+ free(in);
+ ret = _ResolvePath(parent, fids, linkbuf, 0);
+ }
+ free(linkbuf);
+ } else { /* mountpoint */
+ afs_dprintf(("EvalMountPoint %s...\n", linkbuf));
+ linkbufq = strchr(linkbuf, ':');
+ cell = in->cell;
+ v = afscp_VolumeById(cell, in->fid.Volume);
+ free(in);
+ if (v == NULL) {
+ free(linkbuf);
+ afscp_errno = ENODEV;
+ return NULL;
+ }
+ voltype = v->voltype;
+ if (linkbuf[0] == '%')
+ voltype = RWVOL;
+ if (linkbufq == NULL) {
+ linkbufq = linkbuf + 1;
+ } else {
+ *linkbufq++ = 0;
+ cell = afscp_CellByName(linkbuf + 1, NULL);
+ if (linkbuf[0] != '%')
+ voltype = ROVOL;
+ }
+ if (cell == NULL) {
+ free(linkbuf);
+ afscp_errno = ENODEV;
+ return NULL;
+ }
+ len = strnlen(linkbufq, s->Length + 1);
+ if (len < 2) {
+ free(linkbuf);
+ afscp_errno = ENODEV;
+ return NULL;
+ }
+ len = strnlen(linkbufq, s->Length + 1);
+ linkbufq[len - 1] = 0; /* eliminate trailer */
+ if (getvolumeroot(cell, voltype, linkbufq, &ret)) {
+ free(linkbuf);
+ return NULL;
+ }
+ free(linkbuf);
+ }
+ return ret;
}
-static struct afs_venusfid *_ResolvePath(const struct afs_venusfid *start,
- fidstack infids, char *path,
- int follow) {
- struct afs_venusfid *ret,*cwd,*parent;
- struct AFSFetchStatus s;
- char *p,*q;
- int code;
- int linkcount;
- fidstack fids;
-
- p=path;
- ret=cwd=dupfid(start);
- fids=infids;
- if (!fids)
- fids=fidstack_alloc();
- if (!fids)
- return NULL;
-
- while (p && *p) {
- q=strchr(p, '/');
- if (q) *q++=0;
- if (!strcmp(p,".")) {
- } else if (!strcmp(p,"..")) {
- ret=fidstack_pop(fids);
- if (!ret)
- ret=cwd;
- else
- free(cwd);
- } else {
- ret=ResolveName(cwd, p);
- if (!ret) {
- afscp_dprintf(("Lookup %s in %lu.%lu.%lu failed\n", p, cwd->fid.Volume, cwd->fid.Vnode, cwd->fid.Unique));
- free(cwd);
- if (!infids)
- fidstack_free(fids);
- return NULL;
-
- }
- afscp_dprintf(("Lookup %s in %lu.%lu.%lu->%lu.%lu.%lu\n", p, cwd->fid.Volume, cwd->fid.Vnode, cwd->fid.Unique, ret->fid.Volume, ret->fid.Vnode, ret->fid.Unique));
- linkcount=0;
-
- retry:
- if ((ret->fid.Vnode & 1) == 0) { /* not a directory; check for link */
- code=afs_GetStatus(ret, &s);
- if (code) {
- if (!infids)
- fidstack_free(fids);
- free(cwd);
- free(ret);
- return NULL;
- }
- if (s.FileType == SymbolicLink) {
- if (linkcount++ > 5) {
- afs_errno=ELOOP;
- if (!infids)
- fidstack_free(fids);
- free(cwd);
- free(ret);
- return NULL;
- }
- ret=HandleLink(ret, cwd, fids, follow, &s, (q==NULL));
- if (!ret) {
- free(cwd);
- if (!infids)
- fidstack_free(fids);
- return NULL;
- }
- afscp_dprintf((" ....-> %lu.%lu.%lu\n", ret->fid.Volume, ret->fid.Vnode, ret->fid.Unique));
- goto retry;
- } else {
- if (q) {
- afs_errno=ENOTDIR;
- free(cwd);
- free(ret);
- if (!infids)
- fidstack_free(fids);
- return NULL;
- }
- }
- }
- fidstack_push(fids,cwd);
- }
- cwd=ret;
-
- if (q)
- while (*q == '/')
- q++;
- p=q;
- }
- if (!infids)
- fidstack_free(fids);
- return ret;
+static struct afscp_venusfid *
+_ResolvePath(const struct afscp_venusfid *start, fidstack infids,
+ char *path, int follow)
+{
+ struct afscp_venusfid *ret, *cwd;
+ struct AFSFetchStatus s;
+ char *p, *q;
+ int code;
+ int linkcount;
+ fidstack fids;
+
+ p = path;
+ ret = cwd = afscp_DupFid(start);
+ fids = infids;
+ if (fids == NULL)
+ fids = fidstack_alloc();
+ if (fids == NULL) {
+ return NULL;
+ }
+
+ while (p && *p) {
+ q = strchr(p, '/');
+ if (q)
+ *q++ = 0;
+ if (strcmp(p, ".") == 0) {
+ /* do nothing */
+ } else if (strcmp(p, "..") == 0) {
+ ret = fidstack_pop(fids);
+ if (ret == NULL)
+ ret = cwd;
+ else
+ free(cwd);
+ } else {
+ ret = afscp_ResolveName(cwd, p);
+ if (ret == NULL) {
+ afs_dprintf(("Lookup %s in %lu.%lu.%lu failed\n", p,
+ cwd->fid.Volume, cwd->fid.Vnode,
+ cwd->fid.Unique));
+ free(cwd);
+ if (infids == NULL)
+ fidstack_free(fids);
+ return NULL;
+ }
+ afs_dprintf(("Lookup %s in %lu.%lu.%lu->%lu.%lu.%lu\n", p,
+ cwd->fid.Volume, cwd->fid.Vnode, cwd->fid.Unique,
+ ret->fid.Volume, ret->fid.Vnode, ret->fid.Unique));
+ linkcount = 0;
+
+ retry:
+ if ((ret->fid.Vnode & 1) == 0) { /* not a directory; check for link */
+ code = afscp_GetStatus(ret, &s);
+ if (code != 0) {
+ if (infids == NULL)
+ fidstack_free(fids);
+ free(cwd);
+ free(ret);
+ return NULL;
+ }
+ if (s.FileType == SymbolicLink) {
+ if (linkcount++ > 5) {
+ afscp_errno = ELOOP;
+ if (infids == NULL)
+ fidstack_free(fids);
+ free(cwd);
+ free(ret);
+ return NULL;
+ }
+ ret =
+ afscp_HandleLink(ret, cwd, fids, follow, &s,
+ (q == NULL));
+ if (ret == NULL) {
+ free(cwd);
+ if (infids == NULL)
+ fidstack_free(fids);
+ return NULL;
+ }
+ afs_dprintf((" ....-> %lu.%lu.%lu\n", ret->fid.Volume,
+ ret->fid.Vnode, ret->fid.Unique));
+ goto retry;
+ } else {
+ if (q != NULL) {
+ afscp_errno = ENOTDIR;
+ free(cwd);
+ free(ret);
+ if (infids == NULL)
+ fidstack_free(fids);
+ return NULL;
+ }
+ }
+ }
+ fidstack_push(fids, cwd);
+ }
+ cwd = ret;
+
+ while ((q != NULL) && (*q == '/'))
+ q++;
+ p = q;
+ }
+ if (infids == NULL)
+ fidstack_free(fids);
+ return ret;
}
-/* 3 cases:
- begins with /afs: start in root.afs of cell or home cell
- else begins with /: error
- else start in root.cell of cell or home cell
-*/
-struct afs_venusfid *ResolvePath(const char *path) {
- struct afs_venusfid *root,*ret;
- struct afs_cell *cell;
-
- char *p,*q;
- /* so we can modify the string */
- p=strdup(path);
- if (!p) {
- afs_errno=ENOMEM;
- return NULL;
- }
- cell=afs_defaultcell();
- if (!cell) { afs_errno=EINVAL; return NULL;}
- if (gettoproot(cell, p, &q, &root)) {
- free(p);
- return NULL;
- }
- if (q && *q) {
- ret=_ResolvePath(root, 0, q, 1);
- free(root);
- } else
- ret=root;
- free(p);
- return ret;
+
+/*!
+ * Resolve a path to a FID starting from the root volume
+ *
+ * \param[in] path full path
+ *
+ * \post Returns a venusfid representing the final element of path
+ *
+ * \note There are three cases:
+ * (1) begins with /afs: start in root.afs of cell or home cell
+ * (2) else begins with /: error
+ * (3) else start in root.cell of cell or home cell
+ */
+struct afscp_venusfid *
+afscp_ResolvePath(const char *path)
+{
+ struct afscp_venusfid *root, *ret;
+ struct afscp_cell *cell;
+ int code;
+ char *p, *q;
+ p = strdup(path); /* so we can modify the string */
+ if (p == NULL) {
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ cell = afscp_DefaultCell();
+ if (cell == NULL) {
+ afscp_errno = EINVAL;
+ return NULL;
+ }
+ code = gettoproot(cell, p, &q, &root);
+ if (code != 0) {
+ free(p);
+ return NULL;
+ }
+ if (q && *q) {
+ ret = _ResolvePath(root, 0, q, 1);
+ free(root);
+ } else
+ ret = root;
+ free(p);
+ return ret;
}
-struct afs_venusfid *ResolvePath2(const struct afs_volume *v, const char *path) {
- struct afs_venusfid *root,*ret;
-
- char *p,*q;
- /* so we can modify the string */
- p=strdup(path);
- if (!p) {
- afs_errno=ENOMEM;
- return NULL;
- }
- root=makefid(v->cell, v->id, 1,1);
- while (*p == '/') p++;
- if (*p) {
- ret=_ResolvePath(root, 0, p, 1);
- free(root);
- } else
- ret=root;
- free(p);
- return ret;
+/*!
+ * Resolve a path to a FID starting from the given volume
+ *
+ * \param[in] v volume structure containing id and cell info
+ * \param[in] path path relative to volume v
+ *
+ * \post Returns a venusfid representing the final element of path
+ */
+struct afscp_venusfid *
+afscp_ResolvePathFromVol(const struct afscp_volume *v, const char *path)
+{
+ struct afscp_venusfid *root, *ret;
+ char *p;
+
+ /* so we can modify the string */
+ p = strdup(path);
+ if (p == NULL) {
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ root = afscp_MakeFid(v->cell, v->id, 1, 1);
+ while (*p == '/')
+ p++;
+ if (*p != '\0') {
+ ret = _ResolvePath(root, 0, p, 1);
+ free(root);
+ } else
+ ret = root;
+ free(p);
+ return ret;
}
(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>
+
+#include <roken.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
#include <afs/dir.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <search.h>
#include "afscp.h"
#include "afscp_internal.h"
+int
+afscp_CreateFile(const struct afscp_venusfid *dir, char *name,
+ struct AFSStoreStatus *sst, struct afscp_venusfid **ret)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst, fst;
+ struct AFSVolSync vs;
+ struct AFSCallBack cb;
+ struct AFSFid ff;
+ struct afscp_server *server;
+ struct rx_connection *c;
+ time_t now;
-int afs_CreateFile(const struct afs_venusfid *dir, char *name,
- struct AFSStoreStatus *sst,
- struct afs_venusfid **ret) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst, fst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct AFSFid ff;
- struct afs_volume *volume;
- struct afs_server *server;
- struct rx_call *c;
-
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_CreateFile(server->conns[j], &df, name, sst, &ff,
- &fst, &dfst, &cb, &vs);
- if (code >= 0)
- break;
- }
- }
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- AddCallBack(server, &ff, &fst, &cb);
- if (ret)
- *ret=makefid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
- return 0;
+ if (dir == NULL || name == NULL || sst == NULL) {
+ fprintf(stderr,
+ "afscp_CreateFile called with NULL args, cannot continue\n");
+ return -1;
+ }
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ c = afscp_ServerConnection(server, j);
+ if (c == NULL) {
+ break;
+ }
+ time(&now);
+ code = RXAFS_CreateFile(c, &df, name, sst, &ff,
+ &fst, &dfst, &cb, &vs);
+ if (code >= 0) {
+ break;
+ }
+ }
+ }
+ if (code >= 0) {
+ break;
+ }
+ }
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
+ }
+ _StatStuff(dir, &dfst);
+ afscp_AddCallBack(server, &ff, &fst, &cb, now);
+ if (ret != NULL)
+ *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
+ return 0;
}
-int afs_MakeDir(const struct afs_venusfid *dir, char *name,
- struct AFSStoreStatus *sst,
- struct afs_venusfid **ret) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst, fst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct AFSFid ff;
- struct afs_volume *volume;
- struct afs_server *server;
-
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_MakeDir(server->conns[j], &df, name, sst, &ff,
- &fst, &dfst, &cb, &vs);
+int
+afscp_MakeDir(const struct afscp_venusfid *dir, char *name,
+ struct AFSStoreStatus *sst, struct afscp_venusfid **ret)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst, fst;
+ struct AFSVolSync vs;
+ struct AFSCallBack cb;
+ struct AFSFid ff;
+ struct afscp_server *server;
+ struct rx_connection *c;
+ time_t now;
+
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ c = afscp_ServerConnection(server, j);
+ if (c == NULL)
+ break;
+ time(&now);
+ code = RXAFS_MakeDir(c, &df, name, sst, &ff,
+ &fst, &dfst, &cb, &vs);
+ if (code >= 0)
+ break;
+ }
+ }
if (code >= 0)
- break;
- }
- }
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- AddCallBack(server, &ff, &fst, &cb);
- if (ret)
- *ret=makefid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
- return 0;
+ break;
+ }
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
+ }
+ _StatStuff(dir, &dfst);
+ afscp_AddCallBack(server, &ff, &fst, &cb, now);
+ if (ret != NULL)
+ *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
+ return 0;
}
-int afs_Symlink(const struct afs_venusfid *dir, char *name,
- char *target,
- struct AFSStoreStatus *sst) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst, fst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct AFSFid ff;
- struct afs_volume *volume;
- struct afs_server *server;
-
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_Symlink(server->conns[j], &df, name, target, sst, &ff,
- &fst, &dfst, &vs);
+int
+afscp_Symlink(const struct afscp_venusfid *dir, char *name,
+ char *target, struct AFSStoreStatus *sst)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst, fst;
+ struct AFSVolSync vs;
+ struct AFSFid ff;
+ struct afscp_server *server;
+ struct rx_connection *c;
+
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ c = afscp_ServerConnection(server, j);
+ if (c == NULL)
+ break;
+ code = RXAFS_Symlink(c, &df, name, target, sst,
+ &ff, &fst, &dfst, &vs);
+ if (code >= 0)
+ break;
+ }
+ }
if (code >= 0)
- break;
- }
- }
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- return 0;
+ break;
+ }
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
+ }
+ _StatStuff(dir, &dfst);
+ return 0;
}
-int afs_RemoveFile(const struct afs_venusfid *dir, char *name) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct afs_volume *volume;
- struct afs_server *server;
-
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_RemoveFile(server->conns[j], &df, name, &dfst, &vs);
+int
+afscp_RemoveFile(const struct afscp_venusfid *dir, char *name)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst;
+ struct AFSVolSync vs;
+ struct afscp_server *server;
+ struct rx_connection *c;
+
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ c = afscp_ServerConnection(server, j);
+ if (c == NULL)
+ break;
+ code = RXAFS_RemoveFile(c, &df, name, &dfst, &vs);
+ if (code >= 0)
+ break;
+ }
+ }
if (code >= 0)
- break;
- }
- }
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- return 0;
+ break;
+ }
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
+ }
+ _StatStuff(dir, &dfst);
+ return 0;
}
-int afs_RemoveDir(const struct afs_venusfid *dir, char *name) {
- int code, i, j;
- struct AFSFid df = dir->fid;
- struct afs_volume *vol;
- struct AFSFetchStatus dfst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct afs_volume *volume;
- struct afs_server *server;
-
- vol=afs_volumebyid(dir->cell, dir->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_RemoveDir(server->conns[j], &df, name, &dfst, &vs);
+int
+afscp_RemoveDir(const struct afscp_venusfid *dir, char *name)
+{
+ int code, i, j;
+ struct AFSFid df = dir->fid;
+ struct afscp_volume *vol;
+ struct AFSFetchStatus dfst;
+ struct AFSVolSync vs;
+ struct afscp_server *server;
+ struct rx_connection *c;
+
+ vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ c = afscp_ServerConnection(server, j);
+ if (c == NULL)
+ break;
+ code = RXAFS_RemoveDir(c, &df, name, &dfst, &vs);
+ if (code >= 0)
+ break;
+ }
+ }
if (code >= 0)
- break;
- }
- }
- if (code >= 0)
- break;
- }
- if (code) {
- _StatInvalidate(dir);
- afs_errno=code;
- return -1;
- }
- _StatStuff(dir, &dfst);
- return 0;
+ break;
+ }
+ if (code != 0) {
+ _StatInvalidate(dir);
+ afscp_errno = code;
+ return -1;
+ }
+ _StatStuff(dir, &dfst);
+ return 0;
}
(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>
+
+#include <roken.h>
+
+#include <search.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <search.h>
-#include <sys/stat.h>
-#include <inttypes.h>
#include "afscp.h"
#include "afscp_internal.h"
-struct afs_venusfid *makefid(struct afs_cell *cell, afs_uint32 volume,
- afs_uint32 vnode, afs_uint32 unique)
+/*
+ * Allocate and populate an afscp_venusfid struct from component parts
+ */
+struct afscp_venusfid *
+afscp_MakeFid(struct afscp_cell *cell, afs_uint32 volume,
+ afs_uint32 vnode, afs_uint32 unique)
{
- struct afs_venusfid *ret;
-
- if (!cell)
- return NULL;
- ret=malloc(sizeof(struct afs_venusfid));
- if (!ret) {
- afs_errno=errno;
- return NULL;
- }
- ret->cell=cell;
- ret->fid.Volume=volume;
- ret->fid.Vnode=vnode;
- ret->fid.Unique=unique;
- return ret;
+ struct afscp_venusfid *ret;
+
+ if (cell == NULL) {
+ return NULL;
+ }
+ ret = malloc(sizeof(struct afscp_venusfid));
+ if (ret == NULL) {
+ afscp_errno = errno;
+ return NULL;
+ }
+ ret->cell = cell;
+ ret->fid.Volume = volume;
+ ret->fid.Vnode = vnode;
+ ret->fid.Unique = unique;
+ return ret;
}
-struct afs_venusfid *dupfid(const struct afs_venusfid *in)
+/*
+ * Duplicate an existing afscp_venusfid struct
+ */
+struct afscp_venusfid *
+afscp_DupFid(const struct afscp_venusfid *in)
{
- struct afs_venusfid *ret;
-
- ret=malloc(sizeof(struct afs_venusfid));
- if (!ret) {
- afs_errno=errno;
- return NULL;
- }
- ret->cell=in->cell;
- ret->fid.Volume=in->fid.Volume;
- ret->fid.Vnode=in->fid.Vnode;
- ret->fid.Unique=in->fid.Unique;
- return ret;
+ struct afscp_venusfid *ret;
+
+ ret = malloc(sizeof(struct afscp_venusfid));
+ if (ret == NULL) {
+ afscp_errno = errno;
+ return NULL;
+ }
+ ret->cell = in->cell;
+ ret->fid.Volume = in->fid.Volume;
+ ret->fid.Vnode = in->fid.Vnode;
+ ret->fid.Unique = in->fid.Unique;
+ return ret;
}
-
-static int statcompare(const void *a, const void *b)
+void
+afscp_FreeFid(struct afscp_venusfid *avfp)
{
- const struct afs_statent *sa=a,*sb=b;
- if (sa->me.fid.Vnode < sb->me.fid.Vnode) return -1;
- if (sa->me.fid.Vnode > sb->me.fid.Vnode) return 1;
- if (sa->me.fid.Unique < sb->me.fid.Unique) return -1;
- if (sa->me.fid.Unique > sb->me.fid.Unique) return 1;
- return 0;
+ if (avfp != NULL)
+ free(avfp);
}
-
-int afs_GetStatus(const struct afs_venusfid *fid, struct AFSFetchStatus *s)
+static int
+statcompare(const void *a, const void *b)
{
- struct afs_volume *v;
- struct afs_server *server;
- struct AFSCallBack cb;
- struct AFSVolSync vs;
- struct AFSFid tf = fid->fid;
- struct afs_statent *stored,key;
- void *cached;
-
- int code,i,j;
-
- v=afs_volumebyid(fid->cell, fid->fid.Volume);
- if (!v)
- return -1;
- memset(&key, 0, sizeof(key));
- memcpy(&key.me,fid,sizeof(*fid));
-
- cached=tfind(&key, &v->statcache, statcompare);
- if (cached) {
- stored=*(struct afs_statent **)cached;
- memmove(s, &stored->status,sizeof(*s));
- afscp_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n",
- fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique));
- return 0;
- }
-
-
- code=ENOENT;
- for (i=0;i<v->nservers;i++) {
- server=afs_serverbyindex(v->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs);
- if (!code) {
- AddCallBack(server, &fid->fid, s, &cb); /* calls _StatStuff */
- afscp_dprintf(("Stat %u.%" PRIu32 ".%" PRIu32 ".%" PRIu32 " ok: type %" PRId32 " size %" PRId32 "\n",
- fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique, s->FileType, s->Length));
- return 0;
- }
- }
- }
- }
- afs_errno=code;
- return -1;
+ const struct afscp_statent *sa = a, *sb = b;
+ if (sa->me.fid.Vnode < sb->me.fid.Vnode)
+ return -1;
+ if (sa->me.fid.Vnode > sb->me.fid.Vnode)
+ return 1;
+ if (sa->me.fid.Unique < sb->me.fid.Unique)
+ return -1;
+ if (sa->me.fid.Unique > sb->me.fid.Unique)
+ return 1;
+ return 0;
}
-
-
-int afs_stat(const struct afs_venusfid *fid, struct stat *s)
+int
+afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s)
{
-
- struct AFSFetchStatus status;
- int code;
-
- code=afs_GetStatus(fid, &status);
- if (code)
- return code;
-
- if (status.FileType==File)
- s->st_mode=S_IFREG;
- else if (status.FileType==Directory)
- s->st_mode=S_IFDIR;
- else if (status.FileType==SymbolicLink)
- s->st_mode=S_IFLNK;
- else {
- afs_errno=EINVAL;
- return -1;
- }
- s->st_mode |= (status.UnixModeBits & (~S_IFMT));
- s->st_nlink = status.LinkCount;
- s->st_size =status.Length;
- s->st_uid =status.Owner;
- /*s->st_blksize=status.SegSize;*/
- s->st_atime=s->st_mtime=status.ClientModTime;
- s->st_ctime=status.ServerModTime;
- s->st_gid = status.Group;
- return 0;
+ struct afscp_volume *v;
+ struct afscp_server *server;
+ struct AFSCallBack cb;
+ struct AFSVolSync vs;
+ struct AFSFid tf = fid->fid;
+ struct afscp_statent *stored, key;
+ void *cached;
+ int code, i, j;
+ time_t now;
+
+ v = afscp_VolumeById(fid->cell, fid->fid.Volume);
+ if (v == NULL) {
+ return -1;
+ }
+ memset(&key, 0, sizeof(key));
+ memcpy(&key.me, fid, sizeof(*fid));
+
+ cached = tfind(&key, &v->statcache, statcompare);
+ if (cached != NULL) {
+ stored = *(struct afscp_statent **)cached;
+ memmove(s, &stored->status, sizeof(*s));
+ afs_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n",
+ fid->cell->id, fid->fid.Volume, fid->fid.Vnode,
+ fid->fid.Unique));
+ return 0;
+ }
+
+ code = ENOENT;
+ for (i = 0; i < v->nservers; i++) {
+ server = afscp_ServerByIndex(v->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ time(&now);
+ code = RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs);
+ if (code == 0) {
+ afscp_AddCallBack(server, &fid->fid, s, &cb, now); /* calls _StatStuff */
+ afs_dprintf(("Stat %d.%lu.%lu.%lu"
+ " ok: type %ld size %ld\n",
+ fid->cell->id,
+ afs_printable_uint32_lu(fid->fid.Volume),
+ afs_printable_uint32_lu(fid->fid.Vnode),
+ afs_printable_uint32_lu(fid->fid.Unique),
+ afs_printable_int32_ld(s->FileType),
+ afs_printable_int32_ld(s->Length)));
+ return 0;
+ }
+ }
+ }
+ }
+ afscp_errno = code;
+ return -1;
}
+int
+afscp_Stat(const struct afscp_venusfid *fid, struct stat *s)
+{
-int _StatInvalidate(const struct afs_venusfid *fid) {
- struct afs_volume *v;
- struct afs_statent key;
- void **cached;
-
- v=afs_volumebyid(fid->cell, fid->fid.Volume);
- if (!v)
- return -1;
- memmove(&key.me,fid,sizeof(*fid));
+ struct AFSFetchStatus status;
+ int code;
+
+
+ if (s == NULL || fid == NULL) {
+ fprintf(stderr, "NULL args given to afscp_Stat, cannot continue\n");
+ return -1;
+ }
+
+ code = afscp_GetStatus(fid, &status);
+ if (code != 0) {
+ return code;
+ }
+
+ if (status.FileType == File)
+ s->st_mode = S_IFREG;
+ else if (status.FileType == Directory)
+ s->st_mode = S_IFDIR;
+ else if (status.FileType == SymbolicLink)
+ s->st_mode = S_IFLNK;
+ else {
+ afscp_errno = EINVAL;
+ return -1;
+ }
+ s->st_mode |= (status.UnixModeBits & (~S_IFMT));
+ s->st_nlink = status.LinkCount;
+ s->st_size = status.Length;
+ s->st_uid = status.Owner;
+ /*s->st_blksize=status.SegSize; */
+ s->st_atime = s->st_mtime = status.ClientModTime;
+ s->st_ctime = status.ServerModTime;
+ s->st_gid = status.Group;
+ return 0;
+}
- cached=tfind(&key, &v->statcache, statcompare);
- if (cached) {
- free(*cached);
- tdelete(&key, &v->statcache, statcompare);
- }
- return 0;
+int
+_StatInvalidate(const struct afscp_venusfid *fid)
+{
+ struct afscp_volume *v;
+ struct afscp_statent key;
+ void **cached;
+
+ v = afscp_VolumeById(fid->cell, fid->fid.Volume);
+ if (v == NULL) {
+ return -1;
+ }
+ memmove(&key.me, fid, sizeof(*fid));
+
+ cached = tfind(&key, &v->statcache, statcompare);
+ if (cached != NULL) {
+ free(*cached);
+ tdelete(&key, &v->statcache, statcompare);
+ }
+ return 0;
}
-int _StatStuff(const struct afs_venusfid *fid, const struct AFSFetchStatus *s) {
- struct afs_volume *v;
- struct afs_statent key, *stored;
- void **cached;
-
- v=afs_volumebyid(fid->cell, fid->fid.Volume);
- if (!v)
- return -1;
- memmove(&key.me,fid,sizeof(*fid));
-
- cached=tsearch(&key, &v->statcache, statcompare);
- if (cached) {
- stored=malloc(sizeof(struct afs_statent));
- if (stored) {
- memmove(&stored->me, fid, sizeof(*fid));
- memmove(&stored->status,s,sizeof(*s));
- *(struct afs_statent **)cached=stored;
- } else {
- tdelete(&key, &v->statcache, statcompare);
- }
- }
- return 0;
+int
+_StatStuff(const struct afscp_venusfid *fid, const struct AFSFetchStatus *s)
+{
+ struct afscp_volume *v;
+ struct afscp_statent key, *stored;
+ void **cached;
+
+ v = afscp_VolumeById(fid->cell, fid->fid.Volume);
+ if (v == NULL) {
+ return -1;
+ }
+ memmove(&key.me, fid, sizeof(*fid));
+
+ cached = tsearch(&key, &v->statcache, statcompare);
+ if (cached != NULL) {
+ stored = malloc(sizeof(struct afscp_statent));
+ if (stored != NULL) {
+ memmove(&stored->me, fid, sizeof(*fid));
+ memmove(&stored->status, s, sizeof(*s));
+ *(struct afscp_statent **)cached = stored;
+ } else {
+ tdelete(&key, &v->statcache, statcompare);
+ }
+ }
+ return 0;
}
-int afs_StoreStatus(const struct afs_venusfid *fid, struct AFSStoreStatus *s)
+int
+afscp_StoreStatus(const struct afscp_venusfid *fid, struct AFSStoreStatus *s)
{
- struct afs_volume *v;
- struct afs_server *server;
- struct AFSCallBack cb;
- struct AFSVolSync vs;
- struct AFSFetchStatus fst;
- struct AFSFid tf = fid->fid;
- int code,i,j;
-
- v=afs_volumebyid(fid->cell, fid->fid.Volume);
- if (!v)
- return -1;
-
-
- code=ENOENT;
- for (i=0;i<v->nservers;i++) {
- server=afs_serverbyindex(v->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_StoreStatus(server->conns[j], &tf, s, &fst, &vs);
- if (!code) {
- _StatStuff(fid, &fst); /* calls _StatStuff */
- return 0;
- }
- }
- }
- }
- afs_errno=code;
- return -1;
+ struct afscp_volume *v;
+ struct afscp_server *server;
+ struct AFSVolSync vs;
+ struct AFSFetchStatus fst;
+ struct AFSFid tf = fid->fid;
+ int code, i, j;
+
+ v = afscp_VolumeById(fid->cell, fid->fid.Volume);
+ if (v == NULL) {
+ return -1;
+ }
+
+ code = ENOENT;
+ for (i = 0; i < v->nservers; i++) {
+ server = afscp_ServerByIndex(v->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ code = RXAFS_StoreStatus(server->conns[j], &tf, s, &fst, &vs);
+ if (code == 0) {
+ _StatStuff(fid, &fst); /* calls _StatStuff */
+ return 0;
+ }
+ }
+ }
+ }
+ afscp_errno = code;
+ return -1;
}
(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>
+
+#include <roken.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
#include "afscp.h"
#include "afscp_internal.h"
-ssize_t afs_pread(const struct afs_venusfid *fid, void *buffer, size_t count, off_t offset) {
- struct AFSFetchStatus fst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct AFSFid tf = fid->fid;
- struct afs_volume *vol;
- struct afs_server *server;
-
- struct rx_call *c=NULL;
- int code,code2;
- int i,j,bytes,totalbytes;
- int bytesremaining;
- char *p;
-
- vol=afs_volumebyid(fid->cell, fid->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- c=rx_NewCall(server->conns[j]);
- if (c) {
- p=buffer;
- code=StartRXAFS_FetchData(c, &tf, offset, count);
- if (code) {
- code=rx_EndCall(c,code);
- continue;
- }
- bytes=rx_Read(c,(char *)&bytesremaining,sizeof(afs_int32));
- if (bytes != sizeof(afs_int32)) {
- code=rx_EndCall(c,bytes);
- continue;
- }
- bytesremaining=ntohl(bytesremaining);
- totalbytes=0;
- while (bytesremaining > 0) {
- bytes=rx_Read(c, p, bytesremaining);
- if (bytes <= 0)
- break;
- p+=bytes;
- totalbytes+=bytes;
- bytesremaining-=bytes;
- }
- if (bytesremaining == 0) {
- code2=EndRXAFS_FetchData(c, &fst, &cb, &vs);
- if (code2 == 0)
- AddCallBack(server, &fid->fid, &fst, &cb);
- }
- code=rx_EndCall(c, code2);
- }
- if (code == 0)
- return totalbytes;
- }
- }
- }
- afs_errno=code;
- return -1;
+/* this is not yet 64-bit clean */
+ssize_t
+afscp_PRead(const struct afscp_venusfid * fid, void *buffer,
+ size_t count, off_t offset)
+{
+ struct AFSFetchStatus fst;
+ struct AFSVolSync vs;
+ struct AFSCallBack cb;
+ struct AFSFid tf = fid->fid;
+ struct afscp_volume *vol;
+ struct afscp_server *server;
+ struct rx_call *c = NULL;
+ int code, code2 = 0;
+ int i, j, bytes, totalbytes = 0;
+ int bytesremaining;
+ char *p;
+ time_t now;
+
+ vol = afscp_VolumeById(fid->cell, fid->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ c = rx_NewCall(server->conns[j]);
+ if (c != 0) {
+ p = buffer;
+ code = StartRXAFS_FetchData(c, &tf, offset, count);
+ if (code != 0) {
+ code = rx_EndCall(c, code);
+ continue;
+ }
+ bytes =
+ rx_Read(c, (char *)&bytesremaining,
+ sizeof(afs_int32));
+ if (bytes != sizeof(afs_int32)) {
+ code = rx_EndCall(c, bytes);
+ continue;
+ }
+ bytesremaining = ntohl(bytesremaining);
+ totalbytes = 0;
+ while (bytesremaining > 0) {
+ bytes = rx_Read(c, p, bytesremaining);
+ if (bytes <= 0)
+ break;
+ p += bytes;
+ totalbytes += bytes;
+ bytesremaining -= bytes;
+ }
+ if (bytesremaining == 0) {
+ time(&now);
+ code2 = EndRXAFS_FetchData(c, &fst, &cb, &vs);
+ if (code2 == 0)
+ afscp_AddCallBack(server, &fid->fid, &fst, &cb,
+ now);
+ }
+ code = rx_EndCall(c, code2);
+ }
+ if (code == 0) {
+ return totalbytes;
+ }
+ }
+ }
+ }
+ afscp_errno = code;
+ return -1;
}
-
-
-ssize_t afs_pwrite(const struct afs_venusfid *fid, const void *buffer, size_t count, off_t offset) {
-
- struct AFSFetchStatus fst;
- struct AFSStoreStatus sst;
- struct AFSVolSync vs;
- struct AFSCallBack cb;
- struct AFSFid tf=fid->fid;
- struct afs_volume *vol;
- struct afs_server *server;
-
- struct rx_call *c=NULL;
- int code,code2;
- int i,j,bytes,totalbytes;
- int bytesremaining;
- const char *p;
- size_t filesize;
- time_t now;
-
-
- vol=afs_volumebyid(fid->cell, fid->fid.Volume);
- if (!vol) {
- afs_errno=ENOENT;
- return -1;
- }
- if (vol->voltype != VOLTYPE_RW) {
- afs_errno = EROFS;
- return -1;
- }
-
- code=ENOENT;
- for (i=0;i<vol->nservers;i++) {
- server=afs_serverbyindex(vol->servers[i]);
- if (server && server->naddrs > 0) {
- for (j=0;j < server->naddrs;j++) {
- code=RXAFS_FetchStatus(server->conns[j], &tf, &fst, &cb, &vs);
- if (code)
- continue;
- sst.Mask=AFS_SETMODTIME;
- time(&now);
- sst.ClientModTime = now;
- filesize=fst.Length;
- if (offset + count > filesize)
- filesize = offset + count;
- c=rx_NewCall(server->conns[j]);
- if (c) {
- p=buffer;
- code=StartRXAFS_StoreData(c, &tf, &sst, offset, count, filesize);
- if (code) {
- code=rx_EndCall(c,code);
- continue;
- }
- bytesremaining=htonl(count);
- bytes=rx_Write(c,(char *)&bytesremaining,sizeof(afs_int32));
- if (bytes != sizeof(afs_int32)) {
- code=rx_EndCall(c,bytes);
- continue;
- }
- bytesremaining=count;
- totalbytes=0;
- while (bytesremaining > 0) {
- bytes=rx_Write(c, (char *)p, bytesremaining);
- if (bytes <= 0)
- break;
- p+=bytes;
- totalbytes+=bytes;
- bytesremaining-=bytes;
- }
- if (bytesremaining == 0) {
- code2=EndRXAFS_StoreData(c, &fst, &vs);
- }
- code=rx_EndCall(c, code2);
- }
- if (code == 0)
- return totalbytes;
- }
- }
- }
- afs_errno=code;
- return -1;
+/* this is not yet 64-bit clean */
+ssize_t
+afscp_PWrite(const struct afscp_venusfid * fid, const void *buffer,
+ size_t count, off_t offset)
+{
+ struct AFSFetchStatus fst;
+ struct AFSStoreStatus sst;
+ struct AFSVolSync vs;
+ struct AFSCallBack cb;
+ struct AFSFid tf = fid->fid;
+ struct afscp_volume *vol;
+ struct afscp_server *server;
+ struct rx_call *c = NULL;
+ int code, code2 = 0;
+ int i, j, bytes, totalbytes = 0;
+ int bytesremaining;
+ const char *p;
+ off_t filesize;
+ time_t now;
+
+ vol = afscp_VolumeById(fid->cell, fid->fid.Volume);
+ if (vol == NULL) {
+ afscp_errno = ENOENT;
+ return -1;
+ }
+ if (vol->voltype != RWVOL) {
+ afscp_errno = EROFS;
+ return -1;
+ }
+
+ code = ENOENT;
+ for (i = 0; i < vol->nservers; i++) {
+ server = afscp_ServerByIndex(vol->servers[i]);
+ if (server && server->naddrs > 0) {
+ for (j = 0; j < server->naddrs; j++) {
+ code =
+ RXAFS_FetchStatus(server->conns[j], &tf, &fst, &cb, &vs);
+ if (code != 0)
+ continue;
+ sst.Mask = AFS_SETMODTIME;
+ time(&now);
+ sst.ClientModTime = now;
+ filesize = fst.Length;
+ if (offset + count > filesize)
+ filesize = offset + count;
+ c = rx_NewCall(server->conns[j]);
+ if (c != 0) {
+ p = buffer;
+ code =
+ StartRXAFS_StoreData(c, &tf, &sst, offset, count,
+ filesize);
+ if (code != 0) {
+ code = rx_EndCall(c, code);
+ continue;
+ }
+ /*
+ * seems to write file length to beginning of file -- why?
+ */
+ /*
+ * bytesremaining = htonl(count);
+ * bytes = rx_Write(c, (char *)&bytesremaining,
+ * sizeof(afs_int32));
+ * if (bytes != sizeof(afs_int32)) {
+ * code = rx_EndCall(c, bytes);
+ * continue;
+ * }
+ */
+ bytesremaining = count;
+ totalbytes = 0;
+ while (bytesremaining > 0) {
+ bytes = rx_Write(c, (char *)p, bytesremaining);
+ if (bytes <= 0)
+ break;
+ p += bytes;
+ totalbytes += bytes;
+ bytesremaining -= bytes;
+ }
+ if (bytesremaining == 0) {
+ code2 = EndRXAFS_StoreData(c, &fst, &vs);
+ }
+ code = rx_EndCall(c, code2);
+ }
+ if (code == 0) {
+ return totalbytes;
+ }
+ }
+ }
+ }
+ afscp_errno = code;
+ return -1;
}
-
(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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <sys/select.h>
-#include <sys/stat.h>
-
+#include <afsconfig.h>
#include <afs/param.h>
-#include <lwp.h>
-#include <rx/rx_null.h>
-#include <rx/rx.h>
-#include <com_err.h>
+#include <roken.h>
+#include <rx/rx_null.h>
+#include <rx/rx.h>
#include "afscp.h"
#include "afscp_internal.h"
#define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
#endif
-static int init=0;
-extern int RXAFSCB_ExecuteRequest();
+static int init = 0;
static struct rx_securityClass *sc;
static struct rx_service *serv;
-extern PROCESS rx_listenerPid;
-static int start_cb_server()
-{
- sc=rxnull_NewServerSecurityObject();
- serv=rx_NewService(0,1,"afs", &sc, 1, RXAFSCB_ExecuteRequest);
- if (!serv)
- return 1;
- rx_StartServer(0);
- return 0;
+static int
+start_cb_server(void)
+{
+ sc = rxnull_NewServerSecurityObject();
+ serv = rx_NewService(0, 1, "afs", &sc, 1, RXAFSCB_ExecuteRequest);
+ if (serv == NULL) {
+ return 1;
+ }
+ rx_StartServer(0);
+ return 0;
}
-int afscp_init(const char *cell)
+int
+afscp_Init(const char *cell)
{
- if (init)
- return 0;
- if (_rx_InitRandomPort())
- return -1;
- init=1;
- if (start_cb_server()) {
- printf("Cannot start callback service\n");
- return -1;
- }
- init=2;
- if (cell)
- return afs_setdefaultcell(cell);
- return 0;
+ int code;
+ if (init != 0) {
+ return 0;
+ }
+ code = rx_Init(0);
+ if (code != 0) {
+ return -1;
+ }
+ init = 1;
+ code = start_cb_server();
+ if (code != 0) {
+ printf("Cannot start callback service\n");
+ return -1;
+ }
+ init = 2;
+ if (cell != NULL)
+ code = afscp_SetDefaultCell(cell);
+ else
+ code = 0;
+ return code;
}
-void afscp_finalize(void) {
- if (!init)
- return;
-
- ReturnAllCallBacks();
- IOMGR_Sleep(1);
- rx_Finalize();
-#if 0
- LWP_DestroyProcess(rx_listenerPid);
- close(serv->socket);
- rxi_FreeService(serv);
-#endif
- IOMGR_Finalize();
- LWP_TerminateProcessSupport();
-#if 1
- close(serv->socket);
-#endif
+void
+afscp_Finalize(void)
+{
+ if (init == 0) {
+ return;
+ }
+ afscp_ReturnAllCallBacks();
+ afscp_FreeAllCells();
+ afscp_FreeAllServers();
+ rx_Finalize();
+ close(serv->socket);
}
-
-
+#ifndef AFS_SRC_LIBAFSCP_AFSCP_INTERNAL_H
+#define AFS_SRC_LIBAFSCP_AFSCP_INTERNAL_H
+
#include <afs/param.h>
#include <afs/afsint.h>
#include <afs/cellconfig.h>
-#define MAXADDRS 16
-
-/* AUTORIGHTS */
-struct afs_server
-{
- afsUUID id;
- int index;
- int cell;
- int naddrs;
- afs_uint32 addrs[MAXADDRS];
- struct rx_connection *conns[MAXADDRS];
-};
-struct afs_cell
-{
- int id;
- char name[MAXCELLCHARS];
- struct rx_securityClass *security;
- int scindex;
- struct ubik_client *vlservers;
- int nservers;
- int srvsalloced;
- struct afs_server **fsservers;
- void *volsbyname;
- void *volsbyid;
-};
-
-struct afs_callback
-{
- int valid;
- const struct afs_server *server;
- struct AFSFid fid;
- struct AFSCallBack cb;
-};
-
-struct afs_dirstream
-{
- struct afs_venusfid fid;
- int buflen;
- char *dirbuffer;
- int hashent;
- int entry;
- int dv;
- struct afs_dirent ret;
-};
-struct afs_dircache
-{
- struct afs_venusfid me;
- int buflen;
- char *dirbuffer;
- int dv;
-};
+/* afsint.h conflicts with afscbint.h; provide this here */
+extern int RXAFSCB_ExecuteRequest(struct rx_call *);
-struct afs_statent
-{
- struct afs_venusfid me;
- struct AFSFetchStatus status;
-};
-
-struct afs_openfile
-{
- struct afs_venusfid fid;
- off_t offset;
-};
-
-extern int _rx_InitRandomPort(void);
-extern int _GetSecurityObject(struct afs_cell *);
-extern int _GetVLservers(struct afs_cell *);
-extern int _StatInvalidate(const struct afs_venusfid *fid);
-extern int _StatStuff(const struct afs_venusfid *fid, const struct AFSFetchStatus *s);
-
-#ifdef AFSCP_DEBUG
-#define afscp_dprintf(x) printf x
+/* AUTORIGHTS */
+extern int _GetSecurityObject(struct afscp_cell *);
+extern int _GetVLservers(struct afscp_cell *);
+extern int _StatInvalidate(const struct afscp_venusfid *);
+extern int _StatStuff(const struct afscp_venusfid *,
+ const struct AFSFetchStatus *);
+
+#ifndef AFSCP_DEBUG
+#define afs_dprintf(x)
#else
-#define afscp_dprintf(x)
+#define afs_dprintf(x) printf x
#endif
+
+#endif /* AFS_SRC_LIBAFSCP_AFSCP_INTERNAL_H */
(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>
+
+#include <roken.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
#include <afs/volint.h>
#include <afs/dirpath.h>
#define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
#endif
-#include <stdlib.h>
-#include <string.h>
#include <rx/rx.h>
+#include <krb5.h>
#include "afscp.h"
#include "afscp_internal.h"
-static int afs_ncells=0,afs_cellsalloced=0;
-static struct afs_cell *allcells=NULL;
-static int afs_nservers=0,afs_srvsalloced=0;
-static struct afs_server **allservers=NULL;
-static char *defcell;
-int afs_errno=0;
+static int afscp_ncells = 0, afscp_cellsalloced = 0;
+static struct afscp_cell *allcells = NULL;
+static int afscp_nservers = 0, afscp_srvsalloced = 0;
+static struct afscp_server **allservers = NULL;
+static char *defcell = NULL;
+static char *defrealm = NULL;
+int afscp_errno = 0;
+
+void
+afscp_FreeAllCells(void)
+{
+ int i;
+
+ if (allcells == NULL)
+ return;
+
+ for (i = 0; i < afscp_ncells; i++) {
+ if (allcells[i].realm != NULL)
+ free(allcells[i].realm);
+ if (allcells[i].fsservers != NULL)
+ free(allcells[i].fsservers);
+ }
+
+ free(allcells);
+ allcells = NULL;
+ afscp_ncells = 0;
+ afscp_cellsalloced = 0;
+}
+
+void
+afscp_FreeAllServers(void)
+{
+ if (allservers == NULL)
+ return;
+ free(allservers);
+ allservers = NULL;
+ afscp_nservers = 0;
+ afscp_srvsalloced = 0;
+}
-struct afs_cell *afs_cellbyid(int id)
+struct afscp_cell *
+afscp_CellById(int id)
{
- if (id >= afs_ncells)
- return NULL;
- return &allcells[id];
+ if (id >= afscp_ncells || id < 0)
+ return NULL;
+ return &allcells[id];
}
-struct afs_cell *afs_cellbyname(const char *cellname)
+struct afscp_cell *
+afscp_CellByName(const char *cellname, const char *realmname)
{
- int i;
- struct afs_cell *newlist, *thecell;
-
- for (i=0;i<afs_ncells;i++) {
- if (!strcmp(allcells[i].name, cellname))
- return &allcells[i];
- }
- if (afs_ncells >= afs_cellsalloced) {
- if (afs_cellsalloced)
- afs_cellsalloced = afs_cellsalloced *2;
- else
- afs_cellsalloced = 4;
- newlist=realloc(allcells, afs_cellsalloced * sizeof(struct afs_cell));
- if (!newlist)
- return NULL;
- allcells=newlist;
- }
- thecell=&allcells[afs_ncells];
- memset(thecell, 0, sizeof(struct afs_cell));
- strcpy(thecell->name, cellname);
- if (_GetSecurityObject(thecell))
- return NULL;
- if (_GetVLservers(thecell)) {
- RXS_Close(thecell->security);
- return NULL;
- }
- thecell->id=afs_ncells++;
- return thecell;
+ int i;
+ struct afscp_cell *newlist, *thecell;
+
+ if (cellname == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < afscp_ncells; i++) {
+ if (strcmp(allcells[i].name, cellname) == 0) {
+ return &allcells[i];
+ }
+ }
+ if (afscp_ncells >= afscp_cellsalloced) {
+ if (afscp_cellsalloced)
+ afscp_cellsalloced = afscp_cellsalloced * 2;
+ else
+ afscp_cellsalloced = 4;
+ newlist =
+ realloc(allcells, afscp_cellsalloced * sizeof(struct afscp_cell));
+ if (newlist == NULL) {
+ return NULL;
+ }
+ allcells = newlist;
+ }
+ thecell = &allcells[afscp_ncells];
+ memset(thecell, 0, sizeof(struct afscp_cell));
+ strlcpy(thecell->name, cellname, sizeof(thecell->name));
+ if (realmname != NULL) {
+ thecell->realm = malloc(strlen(realmname) + 1);
+ memset(thecell->realm, 0, strlen(realmname) + 1);
+ strlcpy(thecell->realm, realmname, strlen(realmname) + 1);
+ } else {
+ thecell->realm = NULL;
+ }
+ if (_GetSecurityObject(thecell)) {
+ return NULL;
+ }
+ if (_GetVLservers(thecell)) {
+ RXS_Close(thecell->security);
+ return NULL;
+ }
+ thecell->id = afscp_ncells++;
+ return thecell;
}
-struct afs_cell *afs_defaultcell(void)
+
+struct afscp_cell *
+afscp_DefaultCell(void)
{
- struct afsconf_dir *dir;
- char localcell[MAXCELLCHARS+1];
- int code;
-
-
- if (defcell) {
- return afs_cellbyname(defcell);
- }
-
- dir=afsconf_Open(AFSCONF_CLIENTNAME);
- if (!dir) {
- afs_errno=AFSCONF_NODB;
- return NULL;
- }
- code=afsconf_GetLocalCell(dir, localcell, MAXCELLCHARS);
- if (code){
- afs_errno=code;
- return NULL;
- }
- afsconf_Close(dir);
- return afs_cellbyname(localcell);
+ struct afsconf_dir *dir;
+ char localcell[MAXCELLCHARS + 1];
+ int code;
+
+ if (defcell) {
+ return afscp_CellByName(defcell, defrealm);
+ }
+
+ dir = afsconf_Open(AFSCONF_CLIENTNAME);
+ if (dir == NULL) {
+ afscp_errno = AFSCONF_NODB;
+ return NULL;
+ }
+ code = afsconf_GetLocalCell(dir, localcell, MAXCELLCHARS);
+ if (code != 0) {
+ afscp_errno = code;
+ return NULL;
+ }
+ afsconf_Close(dir);
+ return afscp_CellByName(localcell, defrealm);
}
-int afs_setdefaultcell(const char *cellname) {
- struct afs_cell *this;
- char *newdefcell;
- if (!cellname) {
- if (defcell)
- free(defcell);
- defcell=NULL;
- return 0;
- }
-
- this=afs_cellbyname(cellname);
- if (!this)
- return -1;
- newdefcell=strdup(cellname);
- if (!newdefcell)
+int
+afscp_SetDefaultRealm(const char *realmname)
+{
+ /* krb5_error_code k5ec; */
+ krb5_context k5con;
+ char *newdefrealm;
+ int code;
+
+ if (realmname == NULL) {
+ if (defrealm != NULL)
+ free(defrealm);
+ defrealm = NULL;
+ return 0;
+ }
+
+ code = krb5_init_context(&k5con); /* see aklog.c main() */
+ if (code != 0) {
+ return -1;
+ }
+ /* k5ec = */
+ krb5_set_default_realm(k5con, realmname);
+ /* if (k5ec != KRB5KDC_ERR_NONE) {
+ * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE);
+ * return -1;
+ * } */
+ /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */
+ newdefrealm = strdup(realmname);
+ if (newdefrealm == NULL) {
return -1;
- if (defcell)
- free(defcell);
- defcell = newdefcell;
- return 0;
+ }
+ if (defrealm != NULL)
+ free(defrealm);
+ defrealm = newdefrealm;
+ return 0;
}
-int afs_cellid(struct afs_cell *cell) {
- return cell->id;
+int
+afscp_SetDefaultCell(const char *cellname)
+{
+ struct afscp_cell *this;
+ char *newdefcell;
+ if (cellname == NULL) {
+ if (defcell != NULL)
+ free(defcell);
+ defcell = NULL;
+ return 0;
+ }
+
+ this = afscp_CellByName(cellname, defrealm);
+ if (this == NULL) {
+ return -1;
+ }
+ newdefcell = strdup(cellname);
+ if (newdefcell == NULL) {
+ return -1;
+ }
+ if (defcell != NULL)
+ free(defcell);
+ defcell = newdefcell;
+ return 0;
}
-static void _xdr_free(bool_t (*fn)(XDR *xdrs, void *obj), void *obj) {
- XDR xdrs;
- xdrs.x_op=XDR_FREE;
- fn(&xdrs, obj);
+int
+afscp_CellId(struct afscp_cell *cell)
+{
+ if (cell == NULL)
+ return -1;
+ return cell->id;
}
-static bool_t _xdr_bulkaddrs(XDR *xdrs, void *objp) {
- return xdr_bulkaddrs(xdrs, objp);
+
+static void
+_xdr_free(bool_t(*fn) (XDR * xdrs, void *obj), void *obj)
+{
+ XDR xdrs;
+ xdrs.x_op = XDR_FREE;
+ fn(&xdrs, obj);
}
+static bool_t
+_xdr_bulkaddrs(XDR * xdrs, void *objp)
+{
+ return xdr_bulkaddrs(xdrs, objp);
+}
-struct afs_server *afs_serverbyid(struct afs_cell *thecell, afsUUID *u)
+struct afscp_server *
+afscp_ServerById(struct afscp_cell *thecell, afsUUID * u)
{
- /* impliment uniquifiers? */
- int i;
- struct afs_server **newlist;
- struct afs_server **newall;
- struct afs_server *ret;
- afsUUID tmp;
- bulkaddrs addrs;
- struct ListAddrByAttributes attrs;
- afs_int32 nentries, uniq;
-
- char s[512];
-
- afsUUID_to_string(u, s, 511);
- afscp_dprintf(("GetServerByID %s\n", s));
-
- for (i=0;i<thecell->nservers;i++) {
- if (afs_uuid_equal(&thecell->fsservers[i]->id, u))
- return thecell->fsservers[i];
- }
-
- if (thecell->nservers >= thecell->srvsalloced) {
- if (thecell->srvsalloced)
- thecell->srvsalloced = thecell->srvsalloced *2;
- else
- thecell->srvsalloced = 4;
- newlist=realloc(thecell->fsservers,
- thecell->srvsalloced * sizeof(struct afs_server *));
- if (!newlist)
- return NULL;
- thecell->fsservers=newlist;
- }
- ret=malloc(sizeof(struct afs_server));
- if (!ret)
- return NULL;
- thecell->fsservers[thecell->nservers]=ret;
- memmove(&ret->id, u, sizeof(afsUUID));
- ret->cell=thecell->id;
- memset(&tmp, 0, sizeof(tmp));
- memset(&addrs, 0, sizeof(addrs));
- memset(&attrs, 0, sizeof(attrs));
- attrs.Mask = VLADDR_UUID;
- memmove(&attrs.uuid, u, sizeof(afsUUID));
-
- if (ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &tmp,
- &uniq, &nentries, &addrs))
- return NULL;
- if (nentries > MAXADDRS) {
- nentries=MAXADDRS;
- /* XXX I don't want to do *that* much dynamic allocation */
- abort();
- }
-
- ret->naddrs=nentries;
- for (i=0; i< nentries;i++) {
- ret->addrs[i]=htonl(addrs.bulkaddrs_val[i]);
- ret->conns[i]=rx_NewConnection(ret->addrs[i],
+ /* impliment uniquifiers? */
+ int i, code;
+ struct afscp_server **newlist;
+ struct afscp_server **newall;
+ struct afscp_server *ret = NULL;
+ afsUUID tmp;
+ bulkaddrs addrs;
+ struct ListAddrByAttributes attrs;
+ afs_int32 nentries, uniq;
+ char s[512];
+ afsUUID_to_string(u, s, 511);
+ afs_dprintf(("GetServerByID %s\n", s));
+
+ for (i = 0; i < thecell->nservers; i++) {
+ if (afs_uuid_equal(&thecell->fsservers[i]->id, u)) {
+ return thecell->fsservers[i];
+ }
+ }
+
+ if (thecell->nservers >= thecell->srvsalloced) {
+ if (thecell->srvsalloced)
+ thecell->srvsalloced = thecell->srvsalloced * 2;
+ else
+ thecell->srvsalloced = 4;
+ newlist = realloc(thecell->fsservers,
+ thecell->srvsalloced *
+ sizeof(struct afscp_server *));
+ if (newlist == NULL) {
+ return NULL;
+ }
+ thecell->fsservers = newlist;
+ }
+ ret = malloc(sizeof(struct afscp_server));
+ if (ret == NULL) {
+ return NULL;
+ }
+ memset(ret, 0, sizeof(struct afscp_server));
+ thecell->fsservers[thecell->nservers] = ret;
+ memmove(&ret->id, u, sizeof(afsUUID));
+ ret->cell = thecell->id;
+ memset(&tmp, 0, sizeof(tmp));
+ memset(&addrs, 0, sizeof(addrs));
+ memset(&attrs, 0, sizeof(attrs));
+ attrs.Mask = VLADDR_UUID;
+ memmove(&attrs.uuid, u, sizeof(afsUUID));
+
+ code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &tmp,
+ &uniq, &nentries, &addrs);
+ if (code != 0) {
+ return NULL;
+ }
+ if (nentries > AFS_MAXHOSTS) {
+ nentries = AFS_MAXHOSTS;
+ /* XXX I don't want to do *that* much dynamic allocation */
+ abort();
+ }
+
+ ret->naddrs = nentries;
+ for (i = 0; i < nentries; i++) {
+ ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
+ ret->conns[i] = rx_NewConnection(ret->addrs[i],
htons(AFSCONF_FILEPORT),
1, thecell->security,
thecell->scindex);
- }
- _xdr_free(_xdr_bulkaddrs, &addrs);
- thecell->nservers++;
-
- if (afs_nservers >= afs_srvsalloced) {
- if (afs_srvsalloced)
- afs_srvsalloced = afs_srvsalloced *2;
- else
- afs_srvsalloced = 4;
- newall=realloc(allservers,
- afs_srvsalloced * sizeof(struct afs_server *));
- if (!newall)
- return ret;
- allservers=newall;
- }
- ret->index=afs_nservers;
- allservers[afs_nservers++]=ret;
- return ret;
+ }
+ _xdr_free(_xdr_bulkaddrs, &addrs);
+ thecell->nservers++;
+
+ if (afscp_nservers >= afscp_srvsalloced) {
+ if (afscp_srvsalloced)
+ afscp_srvsalloced = afscp_srvsalloced * 2;
+ else
+ afscp_srvsalloced = 4;
+ newall = realloc(allservers,
+ afscp_srvsalloced * sizeof(struct afscp_server *));
+ if (newall == NULL) {
+ return ret;
+ }
+ allservers = newall;
+ }
+ ret->index = afscp_nservers;
+ allservers[afscp_nservers++] = ret;
+ return ret;
}
-struct afs_server *afs_serverbyaddr(struct afs_cell *thecell, afs_uint32 addr)
+struct afscp_server *
+afscp_ServerByAddr(struct afscp_cell *thecell, afs_uint32 addr)
{
- /* impliment uniquifiers? */
- int i,j;
- struct afs_server **newlist;
- struct afs_server **newall;
- struct afs_server *ret;
- afsUUID uuid;
- bulkaddrs addrs;
- struct ListAddrByAttributes attrs;
- afs_int32 nentries, code, uniq;
-
-
- for (i=0;i<thecell->nservers;i++) {
- ret=thecell->fsservers[i];
- for (j=0;j<ret->naddrs;j++)
- if (ret->addrs[j] == htonl(addr))
- return ret;
- }
-
- if (thecell->nservers >= thecell->srvsalloced) {
- if (thecell->srvsalloced)
- thecell->srvsalloced = thecell->srvsalloced *2;
- else
- thecell->srvsalloced = 4;
- newlist=realloc(thecell->fsservers,
- thecell->srvsalloced * sizeof(struct afs_server));
- if (!newlist)
- return NULL;
- thecell->fsservers=newlist;
- }
- ret=malloc(sizeof(struct afs_server));
- if (!ret)
- return NULL;
- thecell->fsservers[thecell->nservers]=ret;
- ret->cell=thecell->id;
- memset(&uuid, 0, sizeof(uuid));
- memset(&addrs, 0, sizeof(addrs));
- memset(&attrs, 0, sizeof(attrs));
- attrs.Mask = VLADDR_IPADDR;
- attrs.ipaddr=addr;
-
-
- if ((code=ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &uuid,
- &uniq, &nentries, &addrs))) {
- memset(&ret->id, 0, sizeof(uuid));
- ret->naddrs=1;
- ret->addrs[0]=htonl(addr);
- ret->conns[0]=rx_NewConnection(ret->addrs[0],
- htons(AFSCONF_FILEPORT),
- 1, thecell->security,
- thecell->scindex);
- } else {
- char s[512];
-
- afsUUID_to_string(&uuid, s, 511);
- afscp_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s));
-
- if (nentries > MAXADDRS) {
- nentries=MAXADDRS;
- /* XXX I don't want to do *that* much dynamic allocation */
- abort();
- }
- memmove(&ret->id, &uuid, sizeof(afsUUID));
-
- ret->naddrs=nentries;
- for (i=0; i< nentries;i++) {
- ret->addrs[i]=htonl(addrs.bulkaddrs_val[i]);
- ret->conns[i]=rx_NewConnection(ret->addrs[i],
- htons(AFSCONF_FILEPORT),
- 1, thecell->security,
- thecell->scindex);
- }
- _xdr_free(_xdr_bulkaddrs, &addrs);
- }
-
- thecell->nservers++;
- if (afs_nservers >= afs_srvsalloced) {
- if (afs_srvsalloced)
- afs_srvsalloced = afs_srvsalloced *2;
- else
- afs_srvsalloced = 4;
- newall=realloc(allservers,
- afs_srvsalloced * sizeof(struct afs_server *));
- if (!newall)
- return ret;
- allservers=newall;
- }
- ret->index=afs_nservers;
- allservers[afs_nservers++]=ret;
- return ret;
+ /* implement uniquifiers? */
+ int i, j;
+ struct afscp_server **newlist;
+ struct afscp_server **newall;
+ struct afscp_server *ret = NULL;
+ afsUUID uuid;
+ bulkaddrs addrs;
+ struct ListAddrByAttributes attrs;
+ afs_int32 nentries, code, uniq;
+
+ if (thecell == NULL)
+ return ret; /* cannot continue without thecell */
+
+ for (i = 0; i < thecell->nservers; i++) {
+ ret = thecell->fsservers[i];
+ for (j = 0; j < ret->naddrs; j++)
+ if (ret->addrs[j] == htonl(addr)) {
+ return ret;
+ }
+ }
+
+ if (thecell->nservers >= thecell->srvsalloced) {
+ if (thecell->srvsalloced)
+ thecell->srvsalloced = thecell->srvsalloced * 2;
+ else
+ thecell->srvsalloced = 4;
+ newlist = realloc(thecell->fsservers,
+ thecell->srvsalloced * sizeof(struct afscp_server));
+ if (newlist == NULL) {
+ return NULL;
+ }
+ thecell->fsservers = newlist;
+ }
+ ret = malloc(sizeof(struct afscp_server));
+ if (ret == NULL) {
+ return NULL;
+ }
+ memset(ret, 0, sizeof(struct afscp_server));
+ thecell->fsservers[thecell->nservers] = ret;
+ ret->cell = thecell->id;
+ memset(&uuid, 0, sizeof(uuid));
+ memset(&addrs, 0, sizeof(addrs));
+ memset(&attrs, 0, sizeof(attrs));
+ attrs.Mask = VLADDR_IPADDR;
+ attrs.ipaddr = addr;
+
+ code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &uuid,
+ &uniq, &nentries, &addrs);
+ if (code != 0) {
+ memset(&ret->id, 0, sizeof(uuid));
+ ret->naddrs = 1;
+ ret->addrs[0] = htonl(addr);
+ ret->conns[0] = rx_NewConnection(ret->addrs[0],
+ htons(AFSCONF_FILEPORT),
+ 1, thecell->security,
+ thecell->scindex);
+ } else {
+ char s[512];
+
+ afsUUID_to_string(&uuid, s, 511);
+ afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s));
+
+ if (nentries > AFS_MAXHOSTS) {
+ nentries = AFS_MAXHOSTS;
+ /* XXX I don't want to do *that* much dynamic allocation */
+ abort();
+ }
+ memmove(&ret->id, &uuid, sizeof(afsUUID));
+
+ ret->naddrs = nentries;
+ for (i = 0; i < nentries; i++) {
+ ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
+ ret->conns[i] = rx_NewConnection(ret->addrs[i],
+ htons(AFSCONF_FILEPORT),
+ 1, thecell->security,
+ thecell->scindex);
+ }
+ _xdr_free(_xdr_bulkaddrs, &addrs);
+ }
+
+ thecell->nservers++;
+ if (afscp_nservers >= afscp_srvsalloced) {
+ if (afscp_srvsalloced)
+ afscp_srvsalloced = afscp_srvsalloced * 2;
+ else
+ afscp_srvsalloced = 4;
+ newall = realloc(allservers,
+ afscp_srvsalloced * sizeof(struct afscp_server *));
+ if (newall == NULL) {
+ return ret;
+ }
+ allservers = newall;
+ }
+ ret->index = afscp_nservers;
+ allservers[afscp_nservers++] = ret;
+ return ret;
}
-struct afs_server *afs_anyserverbyaddr(afs_uint32 addr)
+struct afscp_server *
+afscp_AnyServerByAddr(afs_uint32 addr)
{
- /* no idea what this means: "impliment uniquifiers?" */
- int i,j;
- struct afs_server *ret;
-
- for (i=0;i<afs_nservers;i++) {
- ret=allservers[i];
- for (j=0;j<ret->naddrs;j++)
- if (ret->addrs[j] == htonl(addr))
- return ret;
- }
- return NULL;
+ /* implement uniquifiers? */
+ int i, j;
+ struct afscp_server *ret = NULL;
+
+ if (allservers == NULL)
+ return ret;
+ for (i = 0; i < afscp_nservers; i++) {
+ ret = allservers[i];
+ for (j = 0; j < ret->naddrs; j++)
+ if (ret->addrs[j] == htonl(addr)) {
+ return ret;
+ }
+ }
+ return NULL;
}
-struct afs_server *afs_serverbyindex(int i)
+struct afscp_server *
+afscp_ServerByIndex(int i)
{
-
- if (i>= afs_nservers)
- return NULL;
- return allservers[i];
+ if (i >= afscp_nservers || i < 0)
+ return NULL;
+ return allservers[i];
}
-struct rx_connection *afs_serverconnection(const struct afs_server *srv, int i) {
- if (i >= srv->naddrs)
- return NULL;
- return srv->conns[i];
+struct rx_connection *
+afscp_ServerConnection(const struct afscp_server *srv, int i)
+{
+ if (srv == NULL || srv->conns == NULL)
+ return NULL;
+ if (i >= srv->naddrs || i < 0)
+ return NULL;
+ return srv->conns[i];
}
(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 <sys/socket.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
+#include <afsconfig.h>
#include <afs/param.h>
+
+#include <roken.h>
+
+#include <ctype.h>
#include <afs/cellconfig.h>
#ifndef AFSCONF_CLIENTNAME
#include <afs/dirpath.h>
#define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
#endif
-
#include <ubik.h>
-#include <rx/rxkad.h>
#include <rx/rx_null.h>
-
+#include <rx/rxkad.h>
#include <krb5.h>
-
#include "afscp.h"
#include "afscp_internal.h"
-#define HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
-
#ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
#define Z_keydata(keyblock) ((keyblock)->contents)
#define Z_keylen(keyblock) ((keyblock)->length)
#define Z_enctype(keyblock) ((keyblock)->keytype)
#endif
-int _rx_InitRandomPort(void) {
- int sock;
- unsigned int port;
- struct sockaddr_in sin;
-
- sock=socket(PF_INET, SOCK_DGRAM, 0);
- if (sock == -1)
- return errno;
- sin.sin_family=AF_INET;
- sin.sin_addr.s_addr=INADDR_ANY;
- sin.sin_port=0;
- if (bind(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0)
- return errno;
-
- port=sizeof(struct sockaddr_in);
- if (getsockname(sock, (struct sockaddr *)&sin, &port) < 0)
- return errno;
- port=sin.sin_port;
- close(sock);
- return rx_Init(port);
+static int insecure = 0;
+static int try_anonymous = 0;
+int
+afscp_Insecure(void)
+{
+ insecure = 1;
+ return 0;
}
-static int insecure;
-
-int afscp_Insecure(void) {
- insecure=1;
- return 0;
+int
+afscp_AnonymousAuth(int state)
+{
+ try_anonymous = state;
+ return 0;
}
+
static struct afsconf_dir *confdir;
-static int _GetCellInfo(char *cell, struct afsconf_cell *celldata) {
+static int
+_GetCellInfo(char *cell, struct afsconf_cell *celldata)
+{
+ int code;
+ if (confdir == NULL)
+ confdir = afsconf_Open(AFSCONF_CLIENTNAME);
+ if (confdir == NULL) {
+ return AFSCONF_NODB;
+ }
+ code = afsconf_GetCellInfo(confdir, cell, AFSCONF_VLDBSERVICE, celldata);
+ return code;
+}
- if (!confdir)
- confdir=afsconf_Open(AFSCONF_CLIENTNAME);
- if (!confdir)
- return AFSCONF_NODB;
- return afsconf_GetCellInfo(confdir, cell, AFSCONF_VLDBSERVICE, celldata);
+static int
+_GetNullSecurityObject(struct afscp_cell *cell)
+{
+ cell->security = (struct rx_securityClass *)rxnull_NewClientSecurityObject();
+ cell->scindex = RX_SECIDX_NULL;
+ return 0;
}
-int _GetSecurityObject(struct afs_cell *cell) {
- int code;
- krb5_context context;
- krb5_creds match;
- krb5_creds *cred;
- krb5_ccache cc;
- char **realms,*realm;
- struct afsconf_cell celldata;
- char localcell[MAXCELLCHARS];
- struct rx_securityClass *sc;
- struct ktc_encryptionKey k;
- int i;
- rxkad_level l;
-
- code=_GetCellInfo(cell->name, &celldata);
- if (code)
- return code;
+int
+_GetSecurityObject(struct afscp_cell *cell)
+{
+ int code;
+ krb5_context context;
+ krb5_creds match;
+ krb5_creds *cred;
+ krb5_ccache cc;
+ char **realms, *realm, *inst;
+ char name[1024];
+ struct afsconf_cell celldata;
+ char localcell[MAXCELLCHARS + 1];
+ struct rx_securityClass *sc;
+ struct ktc_encryptionKey k;
+ int i;
+ rxkad_level l;
+ code = _GetCellInfo(cell->name, &celldata);
+ if (code != 0) {
+ goto try_anon;
+ }
- code=krb5_init_context(&context);
- if (code)
- return code;
- realm=NULL;
- code=krb5_get_host_realm(context, celldata.hostName[0], &realms);
- if (!code) {
- strcpy(localcell,realms[0]);
- krb5_free_host_realm(context,realms);
- realm=localcell;
- }
- if (!realm) {
- for (i=0; (i < MAXCELLCHARS && cell->name[i]); i++) {
- if (isalpha(cell->name[i]))
- localcell[i]=toupper(cell->name[i]);
- else
- localcell[i]=cell->name[i];
+ code = krb5_init_context(&context); /* see aklog.c main() */
+ if (code != 0) {
+ goto try_anon;
+ }
+
+ if (cell->realm == NULL) {
+ realm = NULL;
+ code = krb5_get_host_realm(context, celldata.hostName[0], &realms);
+
+ if (code == 0) {
+ strlcpy(localcell, realms[0], sizeof(localcell));
+ krb5_free_host_realm(context, realms);
+ realm = localcell;
+ }
+ } else {
+ realm = cell->realm;
+ strlcpy(localcell, realm, MAXCELLCHARS + 1);
}
- localcell[i]='\0';
- realm=localcell;
- }
- cc=NULL;
- code=krb5_cc_default(context, &cc);
-
- memset(&match, 0, sizeof(match));
- Z_enctype(Z_credskey(&match))=ENCTYPE_DES_CBC_CRC;
-
- if (!code)
- code=krb5_cc_get_principal(context, cc, &match.client);
- if (!code)
- code=krb5_build_principal(context, &match.server,
- strlen(realm), realm,
- "afs", cell->name, NULL);
-
- if (code) {
+ if (realm)
+ if (realm == NULL) {
+ for (i = 0; (i < MAXCELLCHARS && cell->name[i]); i++) {
+ if (isalpha(cell->name[i]))
+ localcell[i] = toupper(cell->name[i]);
+ else
+ localcell[i] = cell->name[i];
+ }
+ localcell[i] = '\0';
+ realm = localcell;
+ }
+ cc = NULL;
+ code = krb5_cc_default(context, &cc);
+
+ memset(&match, 0, sizeof(match));
+ Z_enctype(Z_credskey(&match)) = ENCTYPE_DES_CBC_CRC;
+
+ if (code == 0)
+ code = krb5_cc_get_principal(context, cc, &match.client);
+ if (code == 0)
+ code = krb5_build_principal(context, &match.server,
+ strlen(realm), realm,
+ "afs", cell->name, NULL);
+
+ if (code != 0) {
+ krb5_free_cred_contents(context, &match);
+ if (cc)
+ krb5_cc_close(context, cc);
+ krb5_free_context(context);
+ goto try_anon;
+ }
+
+ code = krb5_get_credentials(context, 0, cc, &match, &cred);
+ if (code != 0) {
+ krb5_free_principal(context, match.server);
+ match.server = NULL;
+
+ inst = cell->name;
+ snprintf(name, sizeof(name), "afs/%s", inst);
+ code = krb5_build_principal(context, &match.server,
+ strlen(realm), realm, name, (void *)NULL);
+ if (code == 0)
+ code = krb5_get_credentials(context, 0, cc, &match, &cred);
+ if (code != 0) {
+ krb5_free_cred_contents(context, &match);
+ if (cc)
+ krb5_cc_close(context, cc);
+ krb5_free_context(context);
+ goto try_anon;
+ }
+ }
+
+ if (insecure)
+ l = rxkad_clear;
+ else
+ l = rxkad_crypt;
+ memcpy(&k.data, Z_keydata(Z_credskey(cred)), 8);
+ sc = (struct rx_securityClass *)rxkad_NewClientSecurityObject
+ (l, &k, RXKAD_TKT_TYPE_KERBEROS_V5,
+ cred->ticket.length, cred->ticket.data);
+ krb5_free_creds(context, cred);
krb5_free_cred_contents(context, &match);
if (cc)
- krb5_cc_close(context, cc);
- krb5_free_context(context);
- return code;
- }
-
- code = krb5_get_credentials(context, 0, cc, &match, &cred);
- if (code) {
- krb5_free_principal(context, match.server);
- match.server=NULL;
- code=krb5_build_principal(context, &match.server,
- strlen(realm), realm,
- "afs", NULL); /* afs@cell instead? */
- if (!code)
- code = krb5_get_credentials(context, 0, cc, &match, &cred);
- if (code) {
- krb5_free_cred_contents(context, &match);
- if (cc)
krb5_cc_close(context, cc);
- krb5_free_context(context);
- return code;
- }
- }
-
- if (insecure)
- l=rxkad_clear;
- else
- l=rxkad_crypt;
- memcpy(&k.data, Z_keydata(Z_credskey(cred)), 8);
- sc = (struct rx_securityClass *)rxkad_NewClientSecurityObject
- (l, &k, RXKAD_TKT_TYPE_KERBEROS_V5,
- cred->ticket.length, cred->ticket.data);
- krb5_free_creds(context, cred);
- krb5_free_cred_contents(context, &match);
- if (cc)
- krb5_cc_close(context, cc);
- krb5_free_context(context);
- cell->security=sc;
- cell->scindex=2;
- return 0;
+ krb5_free_context(context);
+ cell->security = sc;
+ cell->scindex = 2;
+ return 0;
+
+ try_anon:
+ if (try_anonymous)
+ return _GetNullSecurityObject(cell);
+ else
+ return code;
}
-int _GetVLservers(struct afs_cell *cell) {
- struct rx_connection *conns[MAXHOSTSPERCELL+1];
- int i;
- int code;
- struct afsconf_cell celldata;
-
- code=_GetCellInfo(cell->name, &celldata);
- if (code)
- return code;
- for (i=0; i < celldata.numServers; i++) {
- conns[i] = rx_NewConnection(celldata.hostAddr[i].sin_addr.s_addr,
- htons(AFSCONF_VLDBPORT),
- USER_SERVICE_ID, cell->security,
- cell->scindex);
- }
- conns[i]=0;
- return ubik_ClientInit(conns, &cell->vlservers);
+int
+_GetVLservers(struct afscp_cell *cell)
+{
+ struct rx_connection *conns[MAXHOSTSPERCELL + 1];
+ int i;
+ int code;
+ struct afsconf_cell celldata;
+
+ code = _GetCellInfo(cell->name, &celldata);
+ if (code != 0) {
+ return code;
+ }
+
+ for (i = 0; i < celldata.numServers; i++) {
+ conns[i] = rx_NewConnection(celldata.hostAddr[i].sin_addr.s_addr,
+ htons(AFSCONF_VLDBPORT),
+ USER_SERVICE_ID, cell->security,
+ cell->scindex);
+ }
+ conns[i] = 0;
+ return ubik_ClientInit(conns, &cell->vlservers);
}
(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 <roken.h>
+
+#include <search.h>
+
#include <afs/vlserver.h>
#include <afs/vldbint.h>
#include <afs/volint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <inttypes.h>
#include "afscp.h"
#include "afscp_internal.h"
-#include <search.h>
-#include <time.h>
-
-static int icompare(const void *pa, const void *pb) {
- const struct afs_volume *va=pa,*vb=pb;
+static int
+icompare(const void *pa, const void *pb)
+{
+ const struct afscp_volume *va = pa, *vb = pb;
- if (va->id > vb->id) return 1;
- if (va->id < vb->id) return -1;
- return 0;
+ if (va->id > vb->id)
+ return 1;
+ if (va->id < vb->id)
+ return -1;
+ return 0;
}
+static int
+ncompare(const void *pa, const void *pb)
+{
+ const struct afscp_volume *va = pa, *vb = pb;
-static int ncompare(const void *pa, const void *pb) {
- const struct afs_volume *va=pa,*vb=pb;
-
- if (va->voltype > vb->voltype) return 1;
- if (vb->voltype < va->voltype) return -1;
- return strcmp(va->name, vb->name);
+ if (va->voltype > vb->voltype)
+ return 1;
+ if (vb->voltype < va->voltype)
+ return -1;
+ return strcmp(va->name, vb->name);
}
-
-union allvldbentry
-{
- struct uvldbentry u;
- struct nvldbentry n;
- struct vldbentry o;
+union allvldbentry {
+ struct uvldbentry u;
+ struct nvldbentry n;
+ struct vldbentry o;
};
-struct afs_volume *afs_volumebyname(struct afs_cell *cell, const char *vname, afs_int32 intype)
+struct afscp_volume *
+afscp_VolumeByName(struct afscp_cell *cell, const char *vname,
+ afs_int32 intype)
{
- union allvldbentry u;
- struct afs_volume *ret,key;
- struct afs_server *server;
- afs_int32 code,vtype,type,srv;
- void *s;
- struct in_addr i;
+ union allvldbentry u;
+ struct afscp_volume *ret, key;
+ struct afscp_server *server;
+ afs_int32 code, vtype, type, srv;
+ void *s;
+ /* struct in_addr i; */
- if (intype == VOLTYPE_RW)
- vtype=VLSF_RWVOL;
- else if (intype == VOLTYPE_RO)
- vtype=VLSF_ROVOL;
- else if (intype == VOLTYPE_BK)
- vtype=VLSF_BACKVOL;
- else {
- afs_errno=EINVAL;
- return NULL;
- }
+ if (intype == RWVOL)
+ vtype = VLSF_RWVOL;
+ else if (intype == ROVOL)
+ vtype = VLSF_ROVOL;
+ else if (intype == BACKVOL)
+ vtype = VLSF_BACKVOL;
+ else {
+ afscp_errno = EINVAL;
+ return NULL;
+ }
- memset(&key,0, sizeof(key));
- strcpy(key.name,vname);
- key.voltype=vtype;
- s=tfind(&key, &cell->volsbyname, ncompare);
- if (s) {
- ret=*(struct afs_volume **)s;
- return ret;
- }
+ memset(&key, 0, sizeof(key));
+ strlcpy(key.name, vname, sizeof(key.name));
+ key.voltype = vtype;
+ s = tfind(&key, &cell->volsbyname, ncompare);
+ if (s) {
+ ret = *(struct afscp_volume **)s;
+ return ret;
+ }
- type=0;
- if ((code=ubik_VL_GetEntryByNameU(cell->vlservers, 0, (char *)vname, &u.u))
- == RXGEN_OPCODE) {
- type=1;
- if ((code=ubik_VL_GetEntryByNameN(cell->vlservers, 0, (char *)vname, &u.n))
- == RXGEN_OPCODE) {
- type=2;
- code=ubik_VL_GetEntryByNameO(cell->vlservers, 0, (char *)vname, &u.o);
- }
- }
- if (code) {
- afs_errno=code;
- return NULL;
- }
- ret=malloc(sizeof(struct afs_volume));
- if (!ret) {
- afs_errno=ENOMEM;
- return NULL;
- }
- memset(ret,0,sizeof(struct afs_volume));
- strcpy(ret->name, u.u.name);
- ret->nservers=0;
- ret->cell=cell;
- switch (type) {
- case 0:
- ret->id=u.u.volumeId[intype];
- for (srv=0;srv < u.u.nServers;srv++) {
- if ((u.u.serverFlags[srv] & vtype) == 0)
- continue;
- //printf("uvldbentry server %d flags: %x\n",srv, u.u.serverFlags[srv]);
+ type = 0;
+ code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, (char *)vname, &u.u);
+ if (code == RXGEN_OPCODE) {
+ type = 1;
+ code =
+ ubik_VL_GetEntryByNameN(cell->vlservers, 0, (char *)vname, &u.n);
+ if (code == RXGEN_OPCODE) {
+ type = 2;
+ code = ubik_VL_GetEntryByNameO(cell->vlservers, 0, (char *)vname,
+ &u.o);
+ }
+ }
+ if (code != 0) {
+ afscp_errno = code;
+ return NULL;
+ }
+ ret = malloc(sizeof(struct afscp_volume));
+ if (ret == NULL) {
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ memset(ret, 0, sizeof(struct afscp_volume));
+ strlcpy(ret->name, u.u.name, sizeof(ret->name));
+ ret->nservers = 0;
+ ret->cell = cell;
+ switch (type) {
+ case 0:
+ ret->id = u.u.volumeId[intype];
+ for (srv = 0; srv < u.u.nServers; srv++) {
+ if ((u.u.serverFlags[srv] & vtype) == 0)
+ continue;
+ afs_dprintf(("uvldbentry server %d flags: %x\n", srv,
+ u.u.serverFlags[srv]));
- if ((u.u.serverFlags[srv] & VLSERVER_FLAG_UUID) == 0)
- server=afs_serverbyaddr(cell, u.u.serverNumber[srv].time_low);
- else
- server=afs_serverbyid(cell, &u.u.serverNumber[srv]);
- if (!server)
- continue;
- ret->servers[ret->nservers++]=server->index;
- }
- break;
- case 1:
- ret->id=u.n.volumeId[intype];
- for (srv=0;srv < u.n.nServers;srv++) {
- if ((u.n.serverFlags[srv] & vtype) == 0)
- continue;
- server=afs_serverbyaddr(cell, u.n.serverNumber[srv]);
- if (!server)
- continue;
- ret->servers[ret->nservers++]=server->index;
- }
- break;
- case 2:
- ret->id=u.o.volumeId[intype];
- for (srv=0;srv < u.o.nServers;srv++) {
- if ((u.o.serverFlags[srv] & vtype) == 0)
- continue;
- server=afs_serverbyaddr(cell, u.o.serverNumber[srv]);
- if (!server)
- continue;
- ret->servers[ret->nservers++]=server->index;
- }
- break;
- }
- if (!ret->nservers || !ret->id) {
- free(ret);
- return NULL;
- }
+ if ((u.u.serverFlags[srv] & VLSERVER_FLAG_UUID) == 0)
+ server =
+ afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low);
+ else
+ server = afscp_ServerById(cell, &u.u.serverNumber[srv]);
+ if (!server)
+ continue;
+ ret->servers[ret->nservers++] = server->index;
+ }
+ break;
+ case 1:
+ ret->id = u.n.volumeId[intype];
+ for (srv = 0; srv < u.n.nServers; srv++) {
+ if ((u.n.serverFlags[srv] & vtype) == 0)
+ continue;
+ server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]);
+ if (!server)
+ continue;
+ ret->servers[ret->nservers++] = server->index;
+ }
+ break;
+ case 2:
+ ret->id = u.o.volumeId[intype];
+ for (srv = 0; srv < u.o.nServers; srv++) {
+ if ((u.o.serverFlags[srv] & vtype) == 0)
+ continue;
+ server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]);
+ if (!server)
+ continue;
+ ret->servers[ret->nservers++] = server->index;
+ }
+ break;
+ }
+ if (!ret->nservers || !ret->id) {
+ free(ret);
+ return NULL;
+ }
- ret->voltype=intype;
- server=afs_serverbyindex(ret->servers[0]);
- if (server)
- i.s_addr=server->addrs[0];
- else
- i.s_addr=0;
- afscp_dprintf(("New volume BYNAME %s (%lu) on %s (%d)\n", ret->name, ret->id, inet_ntoa(i),ret->servers[0]));
- s=tsearch(&key, &cell->volsbyname, ncompare);
- if (s)
- *(struct afs_volume **)s=ret;
- key.id=ret->id;
- s=tsearch(&key, &cell->volsbyid, icompare);
- if (s)
- *(struct afs_volume **)s=ret;
- return ret;
+ ret->voltype = intype;
+ server = afscp_ServerByIndex(ret->servers[0]);
+ /* if (server != NULL)
+ * i.s_addr = server->addrs[0];
+ * else
+ * i.s_addr = 0; */
+ /* i.s_addr is set but not used later */
+ afs_dprintf(("New volume BYNAME %s (%lu) on %s (%d)\n", ret->name,
+ afs_printable_uint32_lu(ret->id),
+ inet_ntoa(i), ret->servers[0]));
+ s = tsearch(&key, &cell->volsbyname, ncompare);
+ if (s)
+ *(struct afscp_volume **)s = ret;
+ key.id = ret->id;
+ s = tsearch(&key, &cell->volsbyid, icompare);
+ if (s)
+ *(struct afscp_volume **)s = ret;
+ return ret;
}
-struct afs_volume *afs_volumebyid(struct afs_cell *cell, afs_uint32 id)
+struct afscp_volume *
+afscp_VolumeById(struct afscp_cell *cell, afs_uint32 id)
{
- union allvldbentry u;
- struct afs_volume *ret,key;
- struct afs_server *server;
- afs_int32 code,vtype,type,srv;
- int voltype;
- char idbuffer[16];
- void *s;
- struct in_addr i;
-
- memset(&key,0, sizeof(key));
- key.id=id;
- s=tfind(&key, &cell->volsbyid, icompare);
- if (s) {
- ret=*(struct afs_volume **)s;
- return ret;
- }
+ union allvldbentry u;
+ struct afscp_volume *ret, key;
+ struct afscp_server *server;
+ afs_int32 code, vtype, type, srv;
+ int voltype = -1;
+ char idbuffer[16];
+ void *s;
+ /* struct in_addr i; */
- sprintf(idbuffer,"%" PRIu32, id);
- type=0;
- if ((code=ubik_VL_GetEntryByNameU(cell->vlservers, 0, idbuffer, &u.u))
- == RXGEN_OPCODE) {
- type=1;
- if ((code=ubik_VL_GetEntryByIDN(cell->vlservers, 0, id, -1, &u.n))
- == RXGEN_OPCODE) {
- type=2;
- code=ubik_VL_GetEntryByID(cell->vlservers, 0, id, -1, &u.o);
- }
- }
- if (code) {
- afs_errno=code;
- return NULL;
- }
- ret=malloc(sizeof(struct afs_volume));
- if (!ret) {
- afs_errno=ENOMEM;
- return NULL;
- }
+ memset(&key, 0, sizeof(key));
+ key.id = id;
+ s = tfind(&key, &cell->volsbyid, icompare);
+ if (s) {
+ ret = *(struct afscp_volume **)s;
+ return ret;
+ }
- memset(ret,0,sizeof(struct afs_volume));
- strcpy(ret->name, u.u.name);
- ret->nservers=0;
- ret->cell=cell;
+ snprintf(idbuffer, sizeof(idbuffer), "%lu", afs_printable_uint32_lu(id));
+ type = 0;
+ code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, idbuffer, &u.u);
+ if (code == RXGEN_OPCODE) {
+ type = 1;
+ code = ubik_VL_GetEntryByIDN(cell->vlservers, 0, id, -1, &u.n);
+ if (code == RXGEN_OPCODE) {
+ type = 2;
+ code = ubik_VL_GetEntryByID(cell->vlservers, 0, id, -1, &u.o);
+ }
+ }
+ if (code != 0) {
+ afscp_errno = code;
+ return NULL;
+ }
+ ret = malloc(sizeof(struct afscp_volume));
+ if (ret == NULL) {
+ afscp_errno = ENOMEM;
+ return NULL;
+ }
+ memset(ret, 0, sizeof(struct afscp_volume));
+ strlcpy(ret->name, u.u.name, sizeof(ret->name));
+ ret->nservers = 0;
+ ret->cell = cell;
- switch (type) {
- case 0:
- if (id == u.u.volumeId[RWVOL]) {
- vtype=VLSF_RWVOL;
- voltype=VOLTYPE_RW;
- } else if (id == u.u.volumeId[ROVOL]) {
- vtype=VLSF_ROVOL;
- voltype=VOLTYPE_RO;
- } else if (id == u.u.volumeId[BACKVOL]) {
- vtype=VLSF_BACKVOL;
- voltype=VOLTYPE_BK;
- } else {
- vtype=0;
- voltype=-1;
- }
- for (srv=0;srv < u.u.nServers;srv++) {
- if ((u.u.serverFlags[srv] & vtype) == 0)
- continue;
- if ((u.u.serverFlags[srv] & VLSERVER_FLAG_UUID) == 0)
- server=afs_serverbyaddr(cell, u.u.serverNumber[srv].time_low);
- else
- server=afs_serverbyid(cell, &u.u.serverNumber[srv]);
- if (!server)
- continue;
- ret->servers[ret->nservers++]=server->index;
- }
- break;
- case 1:
- if (id == u.n.volumeId[RWVOL]) {
- vtype=VLSF_RWVOL;
- voltype=VOLTYPE_RW;
- } else if (id == u.n.volumeId[ROVOL]) {
- vtype=VLSF_ROVOL;
- voltype=VOLTYPE_RO;
- } else if (id == u.n.volumeId[BACKVOL]) {
- vtype=VLSF_BACKVOL;
- voltype=VOLTYPE_BK;
- } else {
- vtype=0;
- voltype=-1;
- }
- for (srv=0;srv < u.n.nServers;srv++) {
- if ((u.n.serverFlags[srv] & vtype) == 0)
- continue;
- server=afs_serverbyaddr(cell, u.n.serverNumber[srv]);
- if (!server)
- continue;
- ret->servers[ret->nservers++]=server->index;
- }
- break;
- case 2:
- if (id == u.o.volumeId[RWVOL]) {
- vtype=VLSF_RWVOL;
- voltype=VOLTYPE_RW;
- } else if (id == u.o.volumeId[ROVOL]) {
- vtype=VLSF_ROVOL;
- voltype=VOLTYPE_RO;
- } else if (id == u.o.volumeId[BACKVOL]) {
- vtype=VLSF_BACKVOL;
- voltype=VOLTYPE_BK;
- } else {
- vtype=0;
- voltype=-1;
- }
- for (srv=0;srv < u.o.nServers;srv++) {
- if ((u.o.serverFlags[srv] & vtype) == 0)
- continue;
- server=afs_serverbyaddr(cell, u.o.serverNumber[srv]);
- if (!server)
- continue;
- ret->servers[ret->nservers++]=server->index;
- }
- break;
- }
- ret->voltype=voltype;
- server=afs_serverbyindex(ret->servers[0]);
- if (server)
- i.s_addr=server->addrs[0];
- else
- i.s_addr=0;
- afscp_dprintf(("New volume BYID %s (%lu) on %s (%d)\n", ret->name, ret->id, inet_ntoa(i), ret->servers[0]));
- s=tsearch(&key, &cell->volsbyid, icompare);
- if (s)
- *(struct afs_volume **)s=ret;
- strcpy(key.name, ret->name);
- s=tsearch(&key, &cell->volsbyname, ncompare);
- if (s)
- *(struct afs_volume **)s=ret;
- return ret;
+ switch (type) {
+ case 0:
+ if (id == u.u.volumeId[RWVOL]) {
+ vtype = VLSF_RWVOL;
+ voltype = RWVOL;
+ } else if (id == u.u.volumeId[ROVOL]) {
+ vtype = VLSF_ROVOL;
+ voltype = ROVOL;
+ } else if (id == u.u.volumeId[BACKVOL]) {
+ vtype = VLSF_BACKVOL;
+ voltype = BACKVOL;
+ } else {
+ vtype = 0;
+ voltype = -1;
+ }
+ for (srv = 0; srv < u.u.nServers; srv++) {
+ if ((u.u.serverFlags[srv] & vtype) == 0)
+ continue;
+ if ((u.u.serverFlags[srv] & VLSERVER_FLAG_UUID) == 0)
+ server =
+ afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low);
+ else
+ server = afscp_ServerById(cell, &u.u.serverNumber[srv]);
+ if (!server)
+ continue;
+ ret->servers[ret->nservers++] = server->index;
+ }
+ break;
+ case 1:
+ if (id == u.n.volumeId[RWVOL]) {
+ vtype = VLSF_RWVOL;
+ voltype = RWVOL;
+ } else if (id == u.n.volumeId[ROVOL]) {
+ vtype = VLSF_ROVOL;
+ voltype = ROVOL;
+ } else if (id == u.n.volumeId[BACKVOL]) {
+ vtype = VLSF_BACKVOL;
+ voltype = BACKVOL;
+ } else {
+ vtype = 0;
+ voltype = -1;
+ }
+ for (srv = 0; srv < u.n.nServers; srv++) {
+ if ((u.n.serverFlags[srv] & vtype) == 0)
+ continue;
+ server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]);
+ if (server == NULL)
+ continue;
+ ret->servers[ret->nservers++] = server->index;
+ }
+ break;
+ case 2:
+ if (id == u.o.volumeId[RWVOL]) {
+ vtype = VLSF_RWVOL;
+ voltype = RWVOL;
+ } else if (id == u.o.volumeId[ROVOL]) {
+ vtype = VLSF_ROVOL;
+ voltype = ROVOL;
+ } else if (id == u.o.volumeId[BACKVOL]) {
+ vtype = VLSF_BACKVOL;
+ voltype = BACKVOL;
+ } else {
+ vtype = 0;
+ voltype = -1;
+ }
+ for (srv = 0; srv < u.o.nServers; srv++) {
+ if ((u.o.serverFlags[srv] & vtype) == 0)
+ continue;
+ server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]);
+ if (server == NULL)
+ continue;
+ ret->servers[ret->nservers++] = server->index;
+ }
+ break;
+ }
+ ret->voltype = voltype;
+ server = afscp_ServerByIndex(ret->servers[0]);
+ /* if (server)
+ * i.s_addr = server->addrs[0];
+ * else
+ * i.s_addr = 0; */
+ /* i.s_addr is set but not referenced later */
+ afs_dprintf(("New volume BYID %s (%lu) on %s (%d)\n", ret->name,
+ afs_printable_uint32_lu(ret->id), inet_ntoa(i),
+ ret->servers[0]));
+ s = tsearch(&key, &cell->volsbyid, icompare);
+ if (s)
+ *(struct afscp_volume **)s = ret;
+ strlcpy(key.name, ret->name, sizeof(key.name));
+ s = tsearch(&key, &cell->volsbyname, ncompare);
+ if (s)
+ *(struct afscp_volume **)s = ret;
+ return ret;
}
-