libafscp: code cleanup

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>
This commit is contained in:
Chaz Chandler 2010-07-03 15:02:30 -04:00 committed by Derrick Brashear
parent f2e91cc3fe
commit 53377153ec
15 changed files with 3097 additions and 2452 deletions

View 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 \

View 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 \

72
src/libafscp/Makefile.in Normal file
View File

@ -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

View File

@ -1,136 +1,180 @@
#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 ;
#include <afs/afs_consts.h>
#include <afs/cellconfig.h>
#include <afs/dir.h>
#include <afs/afsutil.h>
struct afs_volume
{
struct afs_cell *cell;
afs_uint32 id;
int voltype;
int nservers;
int servers[16];
char name[256];
void *statcache;
void *dircache;
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;
struct afscp_venusfid {
struct afscp_cell *cell;
struct AFSFid fid;
};
extern int afs_errno;
int afscp_init(const char *cellname);
void afscp_finalize(void);
struct afscp_dirent {
afs_uint32 vnode;
afs_uint32 unique;
char name[16 + 32 * (EPP - 2)];
};
#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);
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;
};
#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 afscp_statent {
struct afscp_venusfid me;
struct AFSFetchStatus status;
};
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);
struct afscp_openfile {
struct afscp_venusfid fid;
off_t offset;
};
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_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);
int afscp_Stat(const struct afscp_venusfid *, struct stat *);
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);
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);
struct afscp_volume *afscp_VolumeByName(struct afscp_cell *,
const char *, afs_int32);
struct afscp_volume *afscp_VolumeById(struct afscp_cell *, afs_uint32);
#define DIRMODE_CELL 0
#define DIRMODE_DYNROOT 1
#define DIRMODE_CELL 0
#define DIRMODE_DYNROOT 1
int afscp_SetDirMode(int);
#define VOLTYPE_RW 0
#define VOLTYPE_RO 1
#define VOLTYPE_BK 2
int SetDirMode(int mode);
#endif
#endif /* AFS_SRC_LIBAFSCP_AFSCP_H */

View 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);
if (code >= 0)
break;
}
vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
if (vol == NULL) {
afscp_errno = ENOENT;
return -1;
}
if (code >= 0)
break;
}
if (code) {
_StatInvalidate(dir);
afs_errno=code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
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;
}
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);
if (code >= 0)
break;
}
vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
if (vol == NULL) {
afscp_errno = ENOENT;
return -1;
}
if (code >= 0)
break;
}
if (code) {
_StatInvalidate(dir);
afs_errno=code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
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;
}
if (code != 0) {
_StatInvalidate(dir);
afscp_errno = code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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 (dir == NULL || name == NULL || sst == NULL) {
fprintf(stderr,
"afscp_CreateFile called with NULL args, cannot continue\n");
return -1;
}
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;
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;
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=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);
if (code >= 0)
break;
}
vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
if (vol == NULL) {
afscp_errno = ENOENT;
return -1;
}
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;
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) {
_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;
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=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);
if (code >= 0)
break;
}
vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
if (vol == NULL) {
afscp_errno = ENOENT;
return -1;
}
if (code >= 0)
break;
}
if (code) {
_StatInvalidate(dir);
afs_errno=code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
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) {
_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;
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=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);
if (code >= 0)
break;
}
vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
if (vol == NULL) {
afscp_errno = ENOENT;
return -1;
}
if (code >= 0)
break;
}
if (code) {
_StatInvalidate(dir);
afs_errno=code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
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) {
_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;
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=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);
if (code >= 0)
break;
}
vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
if (vol == NULL) {
afscp_errno = ENOENT;
return -1;
}
if (code >= 0)
break;
}
if (code) {
_StatInvalidate(dir);
afs_errno=code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
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) {
_StatInvalidate(dir);
afscp_errno = code;
return -1;
}
_StatStuff(dir, &dfst);
return 0;
}

View 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;
struct afscp_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;
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;
struct afscp_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;
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
afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s)
{
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));
int afs_stat(const struct afs_venusfid *fid, struct stat *s)
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)
{
struct AFSFetchStatus status;
int code;
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;
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;
}
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));
cached=tfind(&key, &v->statcache, statcompare);
if (cached) {
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 afs_StoreStatus(const struct afs_venusfid *fid, struct AFSStoreStatus *s)
int
_StatInvalidate(const struct afscp_venusfid *fid)
{
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;
struct afscp_volume *v;
struct afscp_statent key;
void **cached;
v=afs_volumebyid(fid->cell, fid->fid.Volume);
if (!v)
return -1;
v = afscp_VolumeById(fid->cell, fid->fid.Volume);
if (v == NULL) {
return -1;
}
memmove(&key.me, fid, sizeof(*fid));
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;
cached = tfind(&key, &v->statcache, statcompare);
if (cached != NULL) {
free(*cached);
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
afscp_StoreStatus(const struct afscp_venusfid *fid, struct AFSStoreStatus *s)
{
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;
}

View 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;
/* 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;
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;
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;
}
/* 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;
}
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;
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;
}

View 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 <roken.h>
#include <rx/rx_null.h>
#include <rx/rx.h>
#include <com_err.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()
static int
start_cb_server(void)
{
sc=rxnull_NewServerSecurityObject();
serv=rx_NewService(0,1,"afs", &sc, 1, RXAFSCB_ExecuteRequest);
if (!serv)
return 1;
rx_StartServer(0);
return 0;
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);
}

View 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
/* afsint.h conflicts with afscbint.h; provide this here */
extern int RXAFSCB_ExecuteRequest(struct rx_call *);
/* 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;
};
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 *);
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;
};
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
#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 */

View 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;
struct afs_cell *afs_cellbyid(int id)
void
afscp_FreeAllCells(void)
{
if (id >= afs_ncells)
return NULL;
return &allcells[id];
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;
}
struct afs_cell *afs_cellbyname(const char *cellname)
void
afscp_FreeAllServers(void)
{
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;
}
struct afs_cell *afs_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);
if (allservers == NULL)
return;
free(allservers);
allservers = NULL;
afscp_nservers = 0;
afscp_srvsalloced = 0;
}
int afs_setdefaultcell(const char *cellname) {
struct afs_cell *this;
char *newdefcell;
if (!cellname) {
if (defcell)
free(defcell);
defcell=NULL;
return 0;
}
struct afscp_cell *
afscp_CellById(int id)
{
if (id >= afscp_ncells || id < 0)
return NULL;
return &allcells[id];
}
this=afs_cellbyname(cellname);
if (!this)
return -1;
newdefcell=strdup(cellname);
if (!newdefcell)
struct afscp_cell *
afscp_CellByName(const char *cellname, const char *realmname)
{
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 afscp_cell *
afscp_DefaultCell(void)
{
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
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;
if (defcell)
free(defcell);
defcell = newdefcell;
return 0;
}
/* 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 (defrealm != NULL)
free(defrealm);
defrealm = newdefrealm;
return 0;
}
int afs_cellid(struct afs_cell *cell) {
return cell->id;
}
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)
int
afscp_SetDefaultCell(const char *cellname)
{
/* 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;
struct afscp_cell *this;
char *newdefcell;
if (cellname == NULL) {
if (defcell != NULL)
free(defcell);
defcell = NULL;
return 0;
}
char s[512];
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;
}
afsUUID_to_string(u, s, 511);
afscp_dprintf(("GetServerByID %s\n", s));
int
afscp_CellId(struct afscp_cell *cell)
{
if (cell == NULL)
return -1;
return cell->id;
}
for (i=0;i<thecell->nservers;i++) {
if (afs_uuid_equal(&thecell->fsservers[i]->id, u))
return thecell->fsservers[i];
}
static void
_xdr_free(bool_t(*fn) (XDR * xdrs, void *obj), void *obj)
{
XDR xdrs;
xdrs.x_op = XDR_FREE;
fn(&xdrs, obj);
}
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));
static bool_t
_xdr_bulkaddrs(XDR * xdrs, void *objp)
{
return xdr_bulkaddrs(xdrs, objp);
}
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();
}
struct afscp_server *
afscp_ServerById(struct afscp_cell *thecell, afsUUID * u)
{
/* 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));
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],
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++;
}
_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;
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;
/* 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;
}
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 (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];
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);
afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s));
afsUUID_to_string(&uuid, s, 511);
afscp_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));
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);
}
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;
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;
/* implement uniquifiers? */
int i, j;
struct afscp_server *ret = NULL;
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;
}
struct afs_server *afs_serverbyindex(int i)
{
if (i>= afs_nservers)
return NULL;
return allservers[i];
}
struct rx_connection *afs_serverconnection(const struct afs_server *srv, int i) {
if (i >= srv->naddrs)
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;
return srv->conns[i];
}
struct afscp_server *
afscp_ServerByIndex(int i)
{
if (i >= afscp_nservers || i < 0)
return NULL;
return allservers[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];
}

View 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) {
if (!confdir)
confdir=afsconf_Open(AFSCONF_CLIENTNAME);
if (!confdir)
return AFSCONF_NODB;
return afsconf_GetCellInfo(confdir, cell, AFSCONF_VLDBSERVICE, 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;
}
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;
static int
_GetNullSecurityObject(struct afscp_cell *cell)
{
cell->security = (struct rx_securityClass *)rxnull_NewClientSecurityObject();
cell->scindex = RX_SECIDX_NULL;
return 0;
}
code=_GetCellInfo(cell->name, &celldata);
if (code)
return code;
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];
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;
}
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;
code = krb5_init_context(&context); /* see aklog.c main() */
if (code != 0) {
goto try_anon;
}
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 (cell->realm == NULL) {
realm = NULL;
code = krb5_get_host_realm(context, celldata.hostName[0], &realms);
if (code) {
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);
}
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;
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 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;
}
}
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;
}
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);
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);
}

View 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;
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 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);
}
union allvldbentry
static int
icompare(const void *pa, const void *pb)
{
struct uvldbentry u;
struct nvldbentry n;
struct vldbentry o;
const struct afscp_volume *va = pa, *vb = pb;
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;
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;
};
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;
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; */
memset(&key,0, sizeof(key));
key.id=id;
s=tfind(&key, &cell->volsbyid, icompare);
if (s) {
ret=*(struct afs_volume **)s;
return ret;
}
memset(&key, 0, sizeof(key));
key.id = id;
s = tfind(&key, &cell->volsbyid, icompare);
if (s) {
ret = *(struct afscp_volume **)s;
return ret;
}
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;
}
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;
memset(ret,0,sizeof(struct afs_volume));
strcpy(ret->name, u.u.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;
}