libafscp: code cleanup
authorChaz Chandler <clc31@inbox.com>
Sat, 3 Jul 2010 19:02:30 +0000 (15:02 -0400)
committerDerrick Brashear <shadow@dementia.org>
Fri, 1 Apr 2011 16:16:45 +0000 (09:16 -0700)
This patch is intended to bring libafscp into accordance with the
current OpenAFS coding standards while also fixing a few small
issues.  Apologies in advance for the numerous whitespace changes.

Change-Id: I606ed5024395319e12e8759f31494ebd27ff6112
Reviewed-on: http://gerrit.openafs.org/4380
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

15 files changed:
Makefile.in
configure.ac
src/libafscp/Makefile.in [new file with mode: 0644]
src/libafscp/afscp.h
src/libafscp/afscp_acl.c
src/libafscp/afscp_callback.c
src/libafscp/afscp_dir.c
src/libafscp/afscp_dirops.c
src/libafscp/afscp_fid.c
src/libafscp/afscp_file.c
src/libafscp/afscp_init.c
src/libafscp/afscp_internal.h
src/libafscp/afscp_server.c
src/libafscp/afscp_util.c
src/libafscp/afscp_volume.c

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