From 94d44d59e3d18f1d450e495a55fdd927e7584948 Mon Sep 17 00:00:00 2001 From: Chaz Chandler Date: Tue, 20 Jul 2010 10:25:20 -0400 Subject: [PATCH] afsio: rewrite using libafscp afsio is a utility for file transfer to and from AFS file space without the help of the AFS client/cache manager. Using libafscp, this (partially rewritten) version of afsio is able to accomplish (1) authenticated access to an AFS path or FID (an existing KerberosV ticket is required), (2) fall back on unauthenticated ("anonymous") access if authentication (token acquisition) fails, and (3) work independtly of the AFS cache manager (afsd need not be running, though CellServDB and ThisCell are currently required). issues: 1) libvldbint and libafsint are not compiled pthreaded. we link in what we need. this should be changed when we are all-pthreaded. 2) venus is not a pthreaded-directory otherwise. same deal: in an all-pthreaded universe, undo the bodge that we do here. 3) venus is not an all-krb5 directory either. slight ick. Change-Id: I946e6eef58ac77c6fb97be256c4c564188201262 Reviewed-on: http://gerrit.openafs.org/4381 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- Makefile.in | 2 +- NTMakefile | 9 +- src/WINNT/afsd/NTMakefile | 24 +- src/venus/Makefile.in | 51 +- src/venus/afsio.c | 1896 +++++++++++++------------------------ 5 files changed, 751 insertions(+), 1231 deletions(-) diff --git a/Makefile.in b/Makefile.in index b40d9f89ec..ac262ecc2f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -349,7 +349,7 @@ dvolser: project tviced usd libafsrpc libafsauthent volser rxosdsrc: rxgen +${COMPILE_PART1} rxosd ${COMPILE_PART2A} source -venus: cmd comerr volser ptserver +venus: cmd comerr volser ptserver libafscp +${COMPILE_PART1} venus ${COMPILE_PART2} +${COMPILE_PART1} venus/test ${COMPILE_PART2} diff --git a/NTMakefile b/NTMakefile index c3a6544736..7198d4291e 100644 --- a/NTMakefile +++ b/NTMakefile @@ -68,6 +68,13 @@ afsreg_headers: $(NTMAKE_HEADERS) $(CD) ..\..\.. +libafscp_headers: + @echo ***** $@ + $(DOCD) $(SRC)\libafscp + $(CD) $(SRC)\libafscp + $(NTMAKE_HEADERS) + $(CD) ..\..\.. + lwp_headers: @echo ***** $@ $(DOCD) $(SRC)\lwp @@ -676,7 +683,7 @@ rpctestlib: fsint libafsrpc $(NTMAKE) $(CD) ..\.. -libafscp: util afs volser vlserver rx auth fsint afsdobjs +libafscp: libafscp_headers util afs volser vlserver rx auth fsint afsdobjs @echo ***** $@ $(DOCD) $(SRC)\$@ $(CD) $(SRC)\$@ diff --git a/src/WINNT/afsd/NTMakefile b/src/WINNT/afsd/NTMakefile index 9b0480b1dd..60dfdf53ed 100644 --- a/src/WINNT/afsd/NTMakefile +++ b/src/WINNT/afsd/NTMakefile @@ -388,7 +388,6 @@ EXELIBS3 = \ $(DESTDIR)\lib\afshcrypto.lib \ $(DESTDIR)\lib\afsroken.lib - # klog.exe $(EXEDIR)\klog.exe: $(OUT)\cklog.obj $(OUT)\klog.res $(EXELIBS) $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib @@ -462,7 +461,7 @@ $(EXEDIR)\fs.exe: $(FSOBJS) $(OUT)\fs.res $(EXELIBS) $(SYMSTORE_IMPORT) # cmdebug.exe -$(EXEDIR)\cmdebug.exe: $(CMDBGOBJS) $(OUT)\cmdebug.res $(EXELIBS2) +$(EXEDIR)\cmdebug.exe: $(CMDBGOBJS) $(OUT)\cmdebug.res $(EXECONLINK) $(EXELIBS2) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib rpcrt4.lib $(_VC_MANIFEST_EMBED_EXE) $(EXEPREP) @@ -470,8 +469,25 @@ $(EXEDIR)\cmdebug.exe: $(CMDBGOBJS) $(OUT)\cmdebug.res $(EXELIBS2) $(SYMSTORE_IMPORT) # afsio.exe -$(EXEDIR)\afsio.exe: $(AFSIOOBJS) $(OUT)\afsio.res $(RXOBJS) $(AFSD_EXELIBS) $(EXELIBS3) - $(EXECONLINK) $(RXOBJS) $(AFSD_EXELIBS) $(EXELIBS3) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib rpcrt4.lib +AFSCPLIB = \ + $(DESTDIR)\lib\afs\afscp.lib + +!IF "$(CPU)" == "IA64" || "$(CPU)" == "AMD64" || "$(CPU)" == "ALPHA64" +KFWLIBS = \ + ..\kfw\lib\$(CPU)\krb5_64.lib \ + ..\kfw\lib\$(CPU)\comerr64.lib \ + dnsapi.lib mpr.lib delayimp.lib +LINKOPTS = /DELAYLOAD:krb5_64.dll /DELAYLOAD:comerr64.dll +!else +KFWLIBS = \ + ..\kfw\lib\$(CPU)\krb5_32.lib \ + ..\kfw\lib\$(CPU)\comerr32.lib \ + dnsapi.lib mpr.lib delayimp.lib +LINKOPTS = /DELAYLOAD:krbv4w32.dll /DELAYLOAD:krb5_32.dll /DELAYLOAD:comerr32.dll +!endif + +$(EXEDIR)\afsio.exe: $(AFSIOOBJS) $(OUT)\afsio.res $(RXOBJS) $(AFSD_EXELIBS) $(EXELIBS3) $(AFSCPLIB) + $(EXECONLINK) $(KFWLIBS) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib rpcrt4.lib $(_VC_MANIFEST_EMBED_EXE) $(EXEPREP) $(CODESIGN_USERLAND) diff --git a/src/venus/Makefile.in b/src/venus/Makefile.in index 5b38c4df77..d3016f1737 100644 --- a/src/venus/Makefile.in +++ b/src/venus/Makefile.in @@ -13,11 +13,28 @@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ +KRB5CFLAGS = @KRB5_CPPFLAGS@ +KRB5LIBS = @KRB5_LIBS@ INCLS=${TOP_INCDIR}/afs/afsint.h \ ${TOP_INCDIR}/afs/cmd.h \ ${TOP_INCDIR}/afs/afsutil.h +AFSIO_INCLS=${TOP_INCDIR}/afs/afsint.h \ + ${TOP_INCDIR}/afs/cmd.h \ + ${TOP_INCDIR}/afs/auth.h \ + ${TOP_INCDIR}/afs/vlserver.h \ + ${TOP_INCDIR}/afs/ihandle.h \ + ${TOP_INCDIR}/afs/com_err.h \ + ${TOP_INCDIR}/afs/afscp.h \ + ${TOP_INCDIR}/afs/afsutil.h + +AFSIO_LIBS=${TOP_LIBDIR}/libafscp.a \ + ${TOP_LIBDIR}/libafsauthent.a \ + ${TOP_LIBDIR}/libafsrpc.a \ + ${TOP_LIBDIR}/libcmd.a \ + $(TOP_LIBDIR)/libafsutil.a + FSLIBS=${TOP_LIBDIR}/libsys.a \ ${TOP_LIBDIR}/libvldb.a \ ${TOP_LIBDIR}/libubik.a \ @@ -47,7 +64,7 @@ CMLIBS=${TOP_LIBDIR}/libsys.a \ LIBS = ${FSLIBS} -all: fs up fstrace cmdebug livesys kdump-build cacheout +all: fs up fstrace cmdebug livesys kdump-build cacheout afsio # # Build targets @@ -69,12 +86,22 @@ fs: fs.o $(LIBS) $(AFS_LDRULE) fs.o ${TOP_LIBDIR}/libprot.a $(LIBS) \ $(LIB_roken) ${XLIBS} -afsio.o: afsio.c ${INCLS} AFS_component_version_number.c +afsio.o: afsio.c ${AFSIO_INCLS} AFS_component_version_number.c + ${PTH_CCRULE} afsio.c +vldbint.cs.o: ${srcdir}/../vlserver/vldbint.cs.c + ${PTH_CCRULE} ${srcdir}/../vlserver/vldbint.cs.c +vldbint.xdr.o: ${srcdir}/../vlserver/vldbint.xdr.c + ${PTH_CCRULE} ${srcdir}/../vlserver/vldbint.xdr.c +afscbint.ss.o: ${srcdir}/../fsint/afscbint.ss.c + ${PTH_CCRULE} ${srcdir}/../fsint/afscbint.ss.c -afsio: afsio.o $(LIBS) - $(AFS_LDRULE) afsio.o ${TOP_LIBDIR}/libprot.a \ - ${TOP_LIBDIR}/libafsint.a $(LIBS) \ - $(LIB_roken) ${XLIBS} +afsio: afsio.o vldbint.cs.o afscbint.ss.o vldbint.xdr.o ${AFSIO_LIBS} + +if test "@BUILD_KRB5@" = "yes"; then \ + $(MT_CC) @KRB5_CPPFLAGS@ $(PTH_LDFLAGS) $(AFS_CFLAGS) -o afsio afsio.o vldbint.cs.o afscbint.ss.o vldbint.xdr.o ${AFSIO_LIBS} \ + $(LIB_hcrypto) $(LIB_roken) ${MT_LIBS} ${XLIBS} ${KRB5LIBS} ; \ + else \ + echo "Skipping afsio (KRB5 build disabled)" ; \ + fi livesys.o: livesys.c ${INCLS} AFS_component_version_number.c @@ -272,7 +299,7 @@ kdump-alpha_linux-@LINUX_VERSION@: kdump-alpha_linux-@LINUX_VERSION@.o # # Install targets # -install: kdump-build fs livesys up fstrace cmdebug +install: kdump-build fs livesys up fstrace cmdebug afsio ${INSTALL} -d ${DESTDIR}${bindir} ${INSTALL} -d ${DESTDIR}${afssrvbindir} ${INSTALL} -d ${DESTDIR}${sbindir} @@ -282,6 +309,9 @@ install: kdump-build fs livesys up fstrace cmdebug ${INSTALL_PROGRAM} up ${DESTDIR}${bindir}/up ${INSTALL_PROGRAM} fstrace ${DESTDIR}${sbindir}/fstrace ${INSTALL_PROGRAM} cmdebug ${DESTDIR}${bindir}/cmdebug + if test "@BUILD_KRB5@" = "yes"; then \ + ${INSTALL_PROGRAM} afsio ${DESTDIR}${bindir}/afsio ; \ + fi -set -x; \ case ${SYS_NAME} in \ sgi_6? ) \ @@ -310,7 +340,7 @@ install: kdump-build fs livesys up fstrace cmdebug ${INSTALL_PROGRAM} kdump64 ${DESTDIR}${sbindir}/kdump; \ fi -dest: kdump-build fs livesys up fstrace cmdebug +dest: kdump-build fs livesys up fstrace cmdebug afsio ${INSTALL} -d ${DEST}/bin ${INSTALL} -d ${DEST}/etc ${INSTALL} -d ${DEST}/root.server/usr/afs/bin @@ -320,6 +350,9 @@ dest: kdump-build fs livesys up fstrace cmdebug ${INSTALL_PROGRAM} up ${DEST}/bin/up ${INSTALL_PROGRAM} fstrace ${DEST}/etc/fstrace ${INSTALL_PROGRAM} cmdebug ${DEST}/bin/cmdebug + if test "@BUILD_KRB5@" = "yes"; then \ + ${INSTALL_PROGRAM} afsio ${DEST}/bin/afsio ; \ + fi -set -x; \ case ${SYS_NAME} in \ sgi_6? ) \ @@ -360,7 +393,7 @@ dest: kdump-build fs livesys up fstrace cmdebug clean: $(RM) -f *.o *.a up fs kdump-* kdump kdump64 core cmdebug \ AFS_component_version_number.c fstrace gcpags livesys dedebug \ - cacheout + cacheout afsio test: cd test; $(MAKE) diff --git a/src/venus/afsio.c b/src/venus/afsio.c index ef8746dcbf..41d7778dc8 100644 --- a/src/venus/afsio.c +++ b/src/venus/afsio.c @@ -24,6 +24,11 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * Revised in 2010 by Chaz Chandler to enhance clientless operations. + * Now utilizes libafscp by Chaskiel Grundman. + * Work funded in part by Sine Nomine Associates (http://www.sinenomine.net/) + */ #include #include @@ -31,8 +36,7 @@ #include -#include -#include +#include #ifdef AFS_NT40_ENV #include #define _CRT_RAND_S @@ -43,72 +47,66 @@ #include #include #else -#include +#include #include #define FSINT_COMMON_XG 1 #endif -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include #include -#include #include +#include +#ifdef HAVE_DIRENT_H +#include +#endif #ifdef HAVE_DIRECT_H #include #endif - +#ifdef AFS_DARWIN_ENV +#include +#else +#include +#endif #include - -#include -#include -#include - #ifdef AFS_PTHREAD_ENV #include pthread_key_t uclient_key; #endif -int readFile(struct cmd_syndesc *as, void *); -int writeFile(struct cmd_syndesc *as, void *); -struct rx_connection *FindRXConnection(afs_uint32 host, u_short port, u_short service, struct rx_securityClass *securityObject, int serviceSecurityIndex); -struct cellLookup * FindCell(char *cellName); +static int readFile(struct cmd_syndesc *, void *); +static int writeFile(struct cmd_syndesc *, void *); +static void printDatarate(void); +static void summarizeDatarate(struct timeval *, const char *); +static int CmdProlog(struct cmd_syndesc *, char **, char **, + char **, char **); +static int ScanFid(char *, struct AFSFid *); +static afs_int32 GetVenusFidByFid(char *, char *, int, struct afscp_venusfid **); +static afs_int32 GetVenusFidByPath(char *, char *, struct afscp_venusfid **); +static int BreakUpPath(char *, char *, char *); -char pnp[255]; -int rxInitDone = 0; +static char pnp[AFSPATHMAX]; /* filename of this program when called */ static int verbose = 0; /* Set if -verbose option given */ -static int CBServiceNeeded = 0; +static int cellGiven = 0; /* Set if -cell option given */ +static int force = 0; /* Set if -force option given */ +static int useFid = 0; /* Set if fidwrite/fidread/fidappend invoked */ +static int append = 0; /* Set if append/fidappend invoked */ static struct timeval starttime, opentime, readtime, writetime; -afs_uint64 xfered=0, oldxfered=0; +static afs_uint64 xfered = 0; static struct timeval now; -static float seconds, datarate, oldseconds; -extern int rxInitDone; #ifdef AFS_NT40_ENV -static afs_int32 rx_mtu = -1; +static int Timezone; /* Roken gettimeofday ignores the timezone */ +#else +static struct timezone Timezone; #endif -afs_uint64 transid = 0; -afs_uint32 expires = 0; -afs_uint32 server_List[MAXHOSTSPERCELL]; -char tmpstr[1024]; -char tmpstr2[1024]; -static struct ubik_client *uclient; -#define BUFFLEN 65536 -#define WRITEBUFFLEN 1024*1024*64 -afsUUID uuid; -MD5_CTX md5; -int md5sum = 0; +#define BUFFLEN 65536 +#define WRITEBUFLEN (BUFFLEN * 1024) +#define MEGABYTE_F 1048576.0f + +static MD5_CTX md5; +static int md5sum = 0; /* Set if -md5 option given */ struct wbuf { struct wbuf *next; @@ -118,812 +116,463 @@ struct wbuf { char buf[BUFFLEN]; }; -struct connectionLookup { - afs_uint32 host; - u_short port; - struct rx_connection *conn; -}; +/*! + * returns difference in seconds between two times + * + * \param[in] from start time + * \param[in] to end time + * + * \post returns "to" minus "from" in seconds + * + */ +static_inline float +time_elapsed(struct timeval *from, struct timeval *to) +{ + return (float)(to->tv_sec + (to->tv_usec * 0.000001) - from->tv_sec - + (from->tv_usec * 0.000001)); +} /* time_elapsed */ -struct cellLookup { - struct cellLookup *next; - struct afsconf_cell info; - struct rx_securityClass *sc; - afs_int32 scIndex; -}; - -struct dirLookup { - struct dirLookup *next; - struct dirLookup *prev; - afs_int32 host; - struct cellLookup *cell; - AFSFid fid; - char name[VL_MAXNAMELEN]; -}; - -struct cellLookup *Cells = 0; -struct dirLookup *Dirs = 0; -char cellFname[256]; - -#define MAX_HOSTS 256 -static struct connectionLookup ConnLookup[MAX_HOSTS]; -static int ConnLookupInitialized = 0; - -struct FsCmdInputs PioctlInputs; -struct FsCmdOutputs PioctlOutputs; - -void +/*! + * prints current average data transfer rate at no less than 30-second intervals + */ +static void printDatarate(void) { - seconds = (float)(now.tv_sec + now.tv_usec *.000001 - -opentime.tv_sec - opentime.tv_usec *.000001); - if ((seconds - oldseconds) > 30.) { - afs_int64 tmp; - tmp = xfered - oldxfered; - datarate = ((afs_uint32) (tmp >> 20)) / (seconds - oldseconds); - fprintf(stderr,"%llu MB transferred, present date rate = %.03f MB/sec.\n", - xfered >> 20, datarate); + static float oldseconds = 0.0; + static afs_uint64 oldxfered = 0; + float seconds; + + gettimeofday(&now, &Timezone); + seconds = time_elapsed(&opentime, &now); + if ((seconds - oldseconds) > 30) { + fprintf(stderr, "%llu MB transferred, present data rate = %.3f MB/sec.\n", xfered >> 20, /* total bytes transferred, in MB */ + (xfered - oldxfered) / (seconds - oldseconds) / MEGABYTE_F); oldxfered = xfered; oldseconds = seconds; } -} +} /* printDatarate */ -void -SetCellFname(char *name) +/*! + * prints overall average data transfer rate and elapsed time + * + * \param[in] tvp current time (to compare with file open time) + * \param[in] xfer_type string identify transfer type ("read" or "write") + */ +static void +summarizeDatarate(struct timeval *tvp, const char *xfer_type) { - struct afsconf_dir *tdir; + float seconds = time_elapsed(&opentime, tvp); - strcpy((char *) &cellFname,"/afs/"); - if (name) - strcat((char *) &cellFname, name); - else { - tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH); - afsconf_GetLocalCell(tdir, &cellFname[5], MAXCELLCHARS); + fprintf(stderr, "Transfer of %llu bytes took %.3f sec.\n", + xfered, seconds); + fprintf(stderr, "Total data rate = %.03f MB/sec. for %s\n", + xfered / seconds / MEGABYTE_F, xfer_type); +} /* summarizeDatarate */ + +/*! + * prints final MD5 sum of all file data transferred + * + * \param[in] fname file name or FID + */ +static void +summarizeMD5(char *fname) +{ + afs_uint32 md5int[4]; + char *p; + + MD5_Final((char *) &md5int[0], &md5); + p = fname + strlen(fname); + while (p > fname) { + if (*(--p) == '/') { + ++p; + break; + } } -} + fprintf(stderr, "%08x%08x%08x%08x %s\n", htonl(md5int[0]), + htonl(md5int[1]), htonl(md5int[2]), htonl(md5int[3]), p); +} /* summarizeMD5 */ -afs_int32 -main (int argc, char **argv) +/*! + * parses all command-line arguments + * + * \param[in] as arguments list + * \param[out] cellp cell name + * \param[out] realmp realm name + * \param[out] fnp filename (either fid or path) + * \param[out] slp "synthesized" (made up) data given + * + * \post returns 0 on success or -1 on error + * + */ +static int +CmdProlog(struct cmd_syndesc *as, char **cellp, char **realmp, + char **fnp, char **slp) { - afs_int32 code; - struct cmd_syndesc *ts; + int i; + struct cmd_parmdesc *pdp; - strcpy(pnp, argv[0]); + if (as == NULL) { + afs_com_err(pnp, EINVAL, "(syndesc is null)"); + return -1; + } + + /* determine which command was requested */ + if (strncmp(as->name, "fid", 3) == 0) /* fidread/fidwrite/fidappend */ + useFid = 1; + if ( (strcmp(as->name, "append") == 0) || + (strcmp(as->name, "fidappend") == 0) ) + append = 1; /* global */ + + /* attempts to ensure loop is bounded: */ + for (pdp = as->parms, i = 0; pdp && (i < as->nParms); i++, pdp++) { + if (pdp->items != NULL) { + if (strcmp(pdp->name, "-verbose") == 0) + verbose = 1; + else if (strcmp(pdp->name, "-md5") == 0) + md5sum = 1; /* global */ + else if (strcmp(pdp->name, "-cell") == 0) { + cellGiven = 1; /* global */ + *cellp = pdp->items->data; + } else if ( (strcmp(pdp->name, "-file") == 0) || + (strcmp(pdp->name, "-fid") == 0) || + (strcmp(pdp->name, "-vnode") == 0) ) + *fnp = pdp->items->data; + else if (strcmp(pdp->name, "-force") == 0) + force = 1; /* global */ + else if (strcmp(pdp->name, "-synthesize") == 0) + *slp = pdp->items->data; + else if (strcmp(pdp->name, "-realm") == 0) + *realmp = pdp->items->data; + } + } + return 0; +} /* CmdProlog */ + +int +main(int argc, char **argv) +{ + afs_int32 code = 0; + struct cmd_syndesc *ts; + char baseName[AFSNAMEMAX]; + + /* try to get only the base name of this executable for use in logs */ + if (BreakUpPath(argv[0], NULL, baseName) > 0) + strlcpy(pnp, baseName, AFSNAMEMAX); + else + strlcpy(pnp, argv[0], AFSPATHMAX); #ifdef AFS_PTHREAD_ENV assert(pthread_key_create(&uclient_key, NULL) == 0); #endif + ts = cmd_CreateSyntax("read", readFile, CMD_REQUIRED, "read a file from AFS"); cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname"); - cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0); + cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0); cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum"); + cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME"); ts = cmd_CreateSyntax("fidread", readFile, CMD_REQUIRED, "read on a non AFS-client a file from AFS"); cmd_IsAdministratorCommand(ts); - cmd_AddParm(ts, "-fid", CMD_SINGLE, CMD_REQUIRED, "volume.vnode.uniquifier"); + cmd_AddParm(ts, "-fid", CMD_SINGLE, CMD_REQUIRED, + "volume.vnode.uniquifier"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname"); - cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0); + cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0); cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum"); + cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME"); ts = cmd_CreateSyntax("write", writeFile, CMD_REQUIRED, "write a file into AFS"); - cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "AFS-filename"); + cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname"); - cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0); + cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0); cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum"); - cmd_AddParm(ts, "-synthesize", CMD_SINGLE, CMD_OPTIONAL, "create data pattern of specified length instead reading from stdin"); + cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, + "overwrite existing file"); + cmd_AddParm(ts, "-synthesize", CMD_SINGLE, CMD_OPTIONAL, + "create data pattern of specified length instead reading from stdin"); + cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME"); ts = cmd_CreateSyntax("fidwrite", writeFile, CMD_REQUIRED, "write a file into AFS"); cmd_IsAdministratorCommand(ts); - cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED, "volume.vnode.uniquifier"); + cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED, + "volume.vnode.uniquifier"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname"); - cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0); + cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0); cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum"); + cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, + "overwrite existing file"); + cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME"); ts = cmd_CreateSyntax("append", writeFile, CMD_REQUIRED, "append to a file in AFS"); - cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "AFS-filename"); + cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname"); - cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0); + cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0); + cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME"); ts = cmd_CreateSyntax("fidappend", writeFile, CMD_REQUIRED, "append to a file in AFS"); cmd_IsAdministratorCommand(ts); - cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED, "volume.vnode.uniquifier"); + cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED, + "volume.vnode.uniquifier"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname"); - cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0); + cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0); + cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME"); + + if (afscp_Init(NULL) != 0) + exit(1); code = cmd_Dispatch(argc, argv); - exit (0); -} -AFS_UNUSED -afs_int32 -HandleLocalAuth(struct rx_securityClass **sc, afs_int32 *scIndex) -{ - static struct afsconf_dir *tdir = NULL; - afs_int32 code; + afscp_Finalize(); + exit(0); +} /* main */ - *sc = NULL; - *scIndex = RX_SECIDX_NULL; - - tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); - if (!tdir) { - fprintf(stderr,"Could not open configuration directory: %s.\n", - AFSDIR_SERVER_ETC_DIRPATH); - return -1; - } - code = afsconf_ClientAuth(tdir, sc, scIndex); - if (code) { - fprintf(stderr,"afsconf_ClientAuth returned %d\n", code); - return -1; - } - return 0; -} - -afs_int32 -AFS_Lookup(struct rx_connection *conn, AFSFid *dirfid, char *name, - AFSFid *outfid, AFSFetchStatus *outstatus, AFSFetchStatus - *dirstatus, AFSCallBack *callback, AFSVolSync *sync) -{ - afs_int32 code = VBUSY; - while (code == VBUSY) { - code = RXAFS_Lookup(conn, dirfid, name, outfid, outstatus, dirstatus, - callback, sync); - if (code == VBUSY) { - fprintf(stderr, "waiting for busy AFS volume %u.\n", - dirfid->Volume); -#ifdef AFS_PTHREAD_ENV - sleep(10); -#else - IOMGR_Sleep(10); -#endif - } - } - return code; -} - -afs_int32 -AFS_FetchStatus(struct rx_connection *conn, AFSFid *fid, AFSFetchStatus - *Status, AFSCallBack *callback, AFSVolSync *sync) -{ - afs_int32 code = VBUSY; - - while (code == VBUSY) { - code = RXAFS_FetchStatus(conn, fid, Status, callback, sync); - if (code == VBUSY) { - fprintf(stderr, "waiting for busy AFS volume %u.\n", - fid->Volume); -#ifdef AFS_PTHREAD_ENV - sleep(10); -#else - IOMGR_Sleep(10); -#endif - } - } - return code; -} - -afs_int32 -StartAFS_FetchData(struct rx_call *call, AFSFid *fid, afs_int32 pos, - afs_int32 len) -{ - afs_int32 code = VBUSY; - while (code == VBUSY) { - code = StartRXAFS_FetchData (call, fid, pos, len); - if (code == VBUSY) { - fprintf(stderr, "waiting for busy AFS volume %u.\n", - fid->Volume); -#ifdef AFS_PTHREAD_ENV - sleep(10); -#else - IOMGR_Sleep(10); -#endif - } - } - return code; -} - -afs_int32 -StartAFS_FetchData64(struct rx_call *call, AFSFid *fid, afs_int64 pos, - afs_int64 len) -{ - afs_int32 code = VBUSY; - while (code == VBUSY) { - code = StartRXAFS_FetchData64 (call, fid, pos, len); - if (code == VBUSY) { - fprintf(stderr, "waiting for busy AFS volume %u.\n", - fid->Volume); -#ifdef AFS_PTHREAD_ENV - sleep(10); -#else - IOMGR_Sleep(10); -#endif - } - } - return code; -} - -afs_int32 -StartAFS_StoreData(struct rx_call *call, AFSFid *fid, AFSStoreStatus *status, - afs_int32 pos, afs_int32 len, afs_int32 len2) -{ - afs_int32 code = VBUSY; - while (code == VBUSY) { - code = StartRXAFS_StoreData (call, fid, status, pos, len, len2); - if (code == VBUSY) { - fprintf(stderr, "waiting for busy AFS volume %u.\n", - fid->Volume); -#ifdef AFS_PTHREAD_ENV - sleep(10); -#else - IOMGR_Sleep(10); -#endif - } - } - return code; -} - -afs_uint32 -StartAFS_StoreData64(struct rx_call *call, AFSFid *fid, AFSStoreStatus *status, - afs_int64 pos, afs_int64 len, afs_int64 len2) -{ - afs_int32 code = VBUSY; - while (code == VBUSY) { - code = StartRXAFS_StoreData64 (call, fid, status, pos, len, len2); - if (code == VBUSY) { - fprintf(stderr, "waiting for busy AFS volume %u.\n", - fid->Volume); -#ifdef AFS_PTHREAD_ENV - sleep(10); -#else - IOMGR_Sleep(10); -#endif - } - } - return code; -} - -afs_int32 -SRXAFSCB_CallBack(struct rx_call *rxcall, AFSCBFids *Fids_Array, - AFSCBs *CallBack_Array) -{ - return 0; -} - -afs_int32 -SRXAFSCB_InitCallBackState(struct rx_call *rxcall) -{ - return 0; -} - -afs_int32 -SRXAFSCB_Probe(struct rx_call *rxcall) -{ - return 0; -} - -afs_int32 -SRXAFSCB_GetCE(struct rx_call *rxcall, - afs_int32 index, - AFSDBCacheEntry * ce) -{ - return(0); -} - -afs_int32 -SRXAFSCB_GetLock(struct rx_call *rxcall, - afs_int32 index, - AFSDBLock * lock) -{ - return(0); -} - -afs_int32 -SRXAFSCB_XStatsVersion(struct rx_call *rxcall, - afs_int32 * versionNumberP) -{ - return(0); -} - -afs_int32 -SRXAFSCB_GetXStats(struct rx_call *rxcall, - afs_int32 clientVersionNumber, - afs_int32 collectionNumber, - afs_int32 * srvVersionNumberP, - afs_int32 * timeP, - AFSCB_CollData * dataP) -{ - return(0); -} - -afs_int32 -SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid) -{ - if ( !afs_uuid_equal(&uuid, a_uuid) ) - return(1); - else - return(0); -} - - -afs_int32 -SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr) -{ - return SRXAFSCB_TellMeAboutYourself(a_call, addr, NULL); -} - -afs_int32 -SRXAFSCB_InitCallBackState2(struct rx_call *a_call, struct interfaceAddr * - addr) -{ - return RXGEN_OPCODE; -} - -afs_int32 -SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid) -{ - return 0; -} - -afs_int32 -SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion, - afs_uint32 *serverVersion, afs_uint32 *configCount, - cacheConfig *config) -{ - return RXGEN_OPCODE; -} - -afs_int32 -SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name) -{ - return RXGEN_OPCODE; -} - -afs_int32 -SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index, - char **a_name, serverList *a_hosts) -{ - return RXGEN_OPCODE; -} - -afs_int32 -SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index, - afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank) -{ - return RXGEN_OPCODE; -} - -afs_int32 -SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call, struct interfaceAddr * - addr, Capabilities *capabilities) -{ -#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 - addr->numberOfInterfaces = 0; -#ifdef notdef - /* return all network interface addresses */ - addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces; - for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) { - addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]); - addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]); - addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]); - } -#endif -#endif - - addr->uuid = uuid; - - if (capabilities) { - 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 0; -} - -afs_int32 -SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum, - char **a_name, serverList *a_hosts) -{ - return RXGEN_OPCODE; -} - -afs_int32 -SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index, - struct AFSDBCacheEntry64 *a_result) -{ - return RXGEN_OPCODE; -} - -void * -InitializeCBService_LWP(void *unused) -{ - struct rx_securityClass *CBsecobj; - struct rx_service *CBService; - - afs_uuid_create(&uuid); - - CBsecobj = (struct rx_securityClass *)rxnull_NewServerSecurityObject(); - if (!CBsecobj) { - fprintf(stderr,"rxnull_NewServerSecurityObject failed for callback service.\n"); - exit(1); - } - CBService = rx_NewService(0, 1, "afs", &CBsecobj, 1, - RXAFSCB_ExecuteRequest); - if (!CBService) { - fprintf(stderr,"rx_NewService failed for callback service.\n"); - exit(1); - } - rx_StartServer(1); - return 0; -} - - -int -InitializeCBService(void) -{ -#define RESTOOL_CBPORT 7102 -#define MAX_PORT_TRIES 1000 -#define LWP_STACK_SIZE (16 * 1024) - afs_int32 code; -#ifdef AFS_PTHREAD_ENV - pthread_t CBservicePid; - pthread_attr_t tattr; -#else - PROCESS CBServiceLWP_ID, parentPid; -#endif - int InitialCBPort; - int CBPort; - -#ifndef NO_AFS_CLIENT - if (!CBServiceNeeded) - return 0; -#endif -#ifndef AFS_PTHREAD_ENV - code = LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid); - if (code != LWP_SUCCESS) { - fprintf(stderr,"Unable to initialize LWP support, code %d\n", - code); - exit(1); - } -#endif - -#if defined(AFS_AIX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_DEC_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI_ENV) - srandom(getpid()); - InitialCBPort = RESTOOL_CBPORT + random() % 1000; -#else /* AFS_AIX_ENV || AFS_SUN_ENV || AFS_OSF_ENV || AFS_SGI_ENV */ -#if defined(AFS_HPUX_ENV) - srand48(getpid()); - InitialCBPort = RESTOOL_CBPORT + lrand48() % 1000; -#else /* AFS_HPUX_ENV */ -#if defined AFS_NT40_ENV - srand(_getpid()); - InitialCBPort = RESTOOL_CBPORT + rand() % 1000; -#else /* AFS_NT40_ENV */ - srand(getpid()); - InitialCBPort = RESTOOL_CBPORT + rand() % 1000; -#endif /* AFS_NT40_ENV */ -#endif /* AFS_HPUX_ENV */ -#endif /* AFS_AIX_ENV || AFS_SUN_ENV || AFS_OSF_ENV || AFS_SGI_ENV */ - - CBPort = InitialCBPort; - do { - code = rx_Init(htons(CBPort)); - if (code) { - if ((code == RX_ADDRINUSE) && - (CBPort < MAX_PORT_TRIES + InitialCBPort)) { - CBPort++; - } else if (CBPort < MAX_PORT_TRIES + InitialCBPort) { - fprintf(stderr, "rx_Init didn't succeed for callback service." - " Tried port numbers %d through %d\n", - InitialCBPort, CBPort); - exit(1); - } else { - fprintf(stderr,"Couldn't initialize callback service " - "because too many users are running this program. " - "Try again later.\n"); - exit(1); - } - } - } while(code); -#ifdef AFS_PTHREAD_ENV - assert(pthread_attr_init(&tattr) == 0); - assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0); - assert(pthread_create( - &CBservicePid, &tattr, InitializeCBService_LWP, 0) - == 0); -#else - code = LWP_CreateProcess(InitializeCBService_LWP, LWP_STACK_SIZE, - LWP_MAX_PRIORITY - 2, (int *) 0, "CBService", - &CBServiceLWP_ID); - if (code != LWP_SUCCESS) { - fprintf(stderr,"Unable to create the callback service LWP, code %d\n", - code); - exit(1); - } -#endif - return 0; -} - -int -ScanVnode(char *fname, char *cell) -{ - afs_int32 i, code = 0; - - SetCellFname(cell); - i = sscanf(fname, "%u.%u.%u", - &PioctlInputs.fid.Volume, - &PioctlInputs.fid.Vnode, - &PioctlInputs.fid.Unique); - if (i != 3) { - PioctlInputs.fid.Volume = 0; - PioctlInputs.fid.Vnode = 0; - PioctlInputs.fid.Unique = 0; - fprintf(stderr,"fs: invalid vnode triple: %s\n", fname); - code = EINVAL; - } - /* - * The following is used to handle the case of unknown uniquifier. We - * just need a valid reference to the volume to direct the RPC to the - * right fileserver. Therefore we take the root directory of the volume. - */ - if (PioctlInputs.fid.Unique == 0) { - PioctlInputs.int32s[0] = PioctlInputs.fid.Vnode; - PioctlInputs.fid.Vnode = 1; - PioctlInputs.fid.Unique = 1; - } - return code; -} - -int -VLDBInit(int noAuthFlag, struct afsconf_cell *info) -{ - afs_int32 code; - - code = ugen_ClientInit(noAuthFlag, (char *) AFSDIR_CLIENT_ETC_DIRPATH, - info->name, 0, &uclient, - NULL, pnp, rxkad_clear, - VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50, - 0, 0, USER_SERVICE_ID); - rxInitDone = 1; - return code; -} - -afs_int32 -get_vnode_hosts(char *fname, char **cellp, afs_int32 *hosts, AFSFid *Fid, - int onlyRW) -{ - struct afsconf_dir *tdir; - struct vldbentry vldbEntry; - afs_int32 i, j, code, *h, len; - struct afsconf_cell info; - afs_int32 mask; - - tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH); - if (!tdir) { - fprintf(stderr,"Could not process files in configuration directory " - "(%s).\n",AFSDIR_CLIENT_ETC_DIRPATH); - return -1; - } - if (!*cellp) { - len = MAXCELLCHARS; - *cellp = (char *) malloc(MAXCELLCHARS); - code = afsconf_GetLocalCell(tdir, *cellp, len); - if (code) return code; - } - code = afsconf_GetCellInfo(tdir, *cellp, AFSCONF_VLDBSERVICE, &info); - if (code) { - fprintf(stderr,"fs: cell %s not in %s/CellServDB\n", - *cellp, AFSDIR_CLIENT_ETC_DIRPATH); - return code; - } - - i = sscanf(fname, "%u.%u.%u", &Fid->Volume, &Fid->Vnode, &Fid->Unique); - if (i != 3) { - fprintf(stderr,"fs: invalid vnode triple: %s\n", fname); - return 1; - } - code = VLDBInit(1, &info); - if (code == 0) { - code = ubik_VL_GetEntryByID(uclient, 0, Fid->Volume, - -1, &vldbEntry); - if (code == VL_NOENT) - fprintf(stderr,"fs: volume %u does not exist in this cell.\n", - Fid->Volume); - if (code) return code; - } - h = hosts; - mask = VLSF_RWVOL; - if (!onlyRW) mask |= VLSF_RWVOL; - for (i=0, j=0; jVolume = (afs_uint32) f1; + fid->Vnode = (afs_uint32) f2; + fid->Unique = (afs_uint32) f3; + } + if (i != 3) { + fid->Volume = 0; + fid->Vnode = 0; + fid->Unique = 0; + code = EINVAL; + afs_com_err(pnp, code, "(invalid FID triple: %s)", fidString); + } + + return code; +} /* ScanFid */ + +/*! + * look up cell info and verify FID info from user input + * + * \param[in] fidString string containing FID info + * \param[in] cellName cell name string + * \param[in] onlyRW bool: 1 = RW vol only, 0 = any vol type + * \param[out] avfpp pointer to venusfid info + * + * \post *avfpp will contain the VenusFid info found for the FID + * given by the used in the string fidString and zero is + * returned. If not found, an appropriate afs error code + * is returned and *avfpp will be NULL. + * + * \note Any non-NULL avfpp returned should later be freed with + * afscp_FreeFid() when no longer needed. + */ +static afs_int32 +GetVenusFidByFid(char *fidString, char *cellName, int onlyRW, + struct afscp_venusfid **avfpp) +{ + afs_int32 code = 0; + struct stat sbuf; + struct afscp_volume *avolp; + + if (*avfpp == NULL) { + *avfpp = malloc(sizeof(struct afscp_venusfid)); + if ( *avfpp == NULL ) { + code = ENOMEM; + return code; } } - if (code) { - fprintf(stderr, "Unable to determine cell for %s\n", fn); - if (errno) { - perror(fn); - if (errno == EINVAL) - fprintf(stderr, "(File might not be in AFS)\n"); - } else - afs_com_err(pnp, code, (char *) 0); + memset(*avfpp, 0, sizeof(struct afscp_venusfid)); + + if (cellName == NULL) { + (*avfpp)->cell = afscp_DefaultCell(); } else { - *cellp = (char *) malloc(strlen(buf)+1); - strcpy(*cellp, buf); - SetCellFname(*cellp); - memset(buf, 0, sizeof(buf)); - status.in = 0; - status.in_size = 0; - status.out = buf; - status.out_size = sizeof(buf); - code = pioctl(fn, VIOCWHEREIS, &status, 0); - if (code) { - fprintf(stderr, "Unable to determine fileservers for %s\n", fn); - if (errno) { - perror(fn); - } + (*avfpp)->cell = afscp_CellByName(cellName, NULL); + } + if ((*avfpp)->cell == NULL) { + if (afscp_errno == 0) + code = EINVAL; + else + code = afscp_errno; + return code; + } + + code = ScanFid(fidString, &((*avfpp)->fid)); + if (code != 0) { + code = EINVAL; + return code; + } + + avolp = afscp_VolumeById((*avfpp)->cell, (*avfpp)->fid.Volume); + if (avolp == NULL) { + if (afscp_errno == 0) + code = ENOENT; + else + code = afscp_errno; + afs_com_err(pnp, code, "(finding volume %lu)", + afs_printable_uint32_lu((*avfpp)->fid.Volume)); + return code; + } + + if ( onlyRW && (avolp->voltype != RWVOL) ) { + avolp = afscp_VolumeByName((*avfpp)->cell, avolp->name, RWVOL); + if (avolp == NULL) { + if (afscp_errno == 0) + code = ENOENT; else - afs_com_err(pnp, code, (char *) 0); - } else { - Tmpafs_int32 = (afs_int32 *)buf; - for (j=0;jfid.Volume)); + return code; } - memset(buf, 0, sizeof(buf)); - status.in_size = 0; - status.out_size = sizeof(buf); - status.in = 0; - status.out = buf; - code = pioctl(fn, VIOCGETFID, &status, 0); - if (code) { - fprintf(stderr, "Unable to determine FID for %s\n", fn); - if (errno) { - perror(fn); - } else { - afs_com_err(pnp, code, (char *) 0); - } - } else { - Tmpafs_int32 = (afs_int32 *)buf; - Fid->Volume = Tmpafs_int32[1]; - Fid->Vnode = Tmpafs_int32[2]; - Fid->Unique = Tmpafs_int32[3]; + (*avfpp)->fid.Volume = avolp->id; /* is this safe? */ + } + + code = afscp_Stat((*avfpp), &sbuf); + if (code != 0) { + afs_com_err(pnp, code, "(stat failed with code %d)", code); + return code; + } + return 0; +} /* GetVenusFidByFid */ + +/*! + * Split a full path up into dirName and baseName components + * + * \param[in] fullPath can be absolute, relative, or local + * \param[out] dirName pointer to allocated char buffer or NULL + * \param[out] baseName pointer to allocated char buffer or NULL + * + * \post To the fulleset extent possible, the rightmost full path + * component will be copied into baseName and all other + * components into dirName (minus the trailing path separator). + * If either dirName or baseName are NULL, only the non-NULL + * pointer will be filled in (but both can't be null or it would + * be pointless) -- so the caller can retrieve, say, only baseName + * if desired. The return code is the number of strings copied: + * 0 if neither dirName nor baseName could be filled in + * 1 if either dirName or baseName were filled in + * 2 if both dirName and baseName were filled in + */ +static int +BreakUpPath(char *fullPath, char *dirName, char *baseName) +{ + char *lastSlash; + size_t dirNameLen = 0; + int code = 0, useDirName = 1, useBaseName = 1; + + if (fullPath == NULL) { + return code; + } + + if (dirName == NULL) + useDirName = 0; + if (baseName == NULL) + useBaseName = 0; + if (!useBaseName && !useDirName) { + /* would be pointless to continue -- must be error in call */ + return code; + } +#ifdef AFS_NT40_ENV + lastSlash = strrchr(fullPath, '\\'); +#else + lastSlash = strrchr(fullPath, '/'); +#endif + if (lastSlash != NULL) { + /* then lastSlash points to the last path separator in fullPath */ + if (useDirName) { + dirNameLen = strlen(fullPath) - strlen(lastSlash); + strlcpy(dirName, fullPath, dirNameLen + 1); + code++; + } + if (useBaseName) { + lastSlash++; + strlcpy(baseName, lastSlash, strlen(lastSlash) + 1); + code++; + } + } else { + /* there are no path separators in fullPath -- it's just a baseName */ + if (useBaseName) { + strlcpy(baseName, fullPath, strlen(fullPath) + 1); + code++; } } return code; -} +} /* BreakUpPath */ -int -DestroyConnections(void) +/*! + * Get the VenusFid info available for the file at AFS path 'fullPath'. + * Works without pioctls/afsd by using libafscp. Analogous to + * get_file_cell() in the previous iteration of afsio. + * + * \param[in] fullPath the file name + * \param[in] cellName the cell name to look up + * \param[out] avfpp pointer to Venus FID info to be filled in + * + * \post If the path resolves successfully (using afscp_ResolvePath), + * then vfpp will contain the Venus FID info (cell info plus + * AFSFid) of the last path segment in fullPath. + */ +static afs_int32 +GetVenusFidByPath(char *fullPath, char *cellName, + struct afscp_venusfid **avfpp) { - int i; + afs_int32 code = 0; - if (!ConnLookupInitialized) return 0; - for (i = 0; i < MAX_HOSTS; i++) { - if (!ConnLookup[i].conn) break; - RXAFS_GiveUpAllCallBacks(ConnLookup[i].conn); - rx_DestroyConnection(ConnLookup[i].conn); + if (fullPath == NULL) { + return -1; } - if (!rxInitDone) - rx_Finalize(); - return 0; -} + if (cellName != NULL) { + code = (afs_int32) afscp_SetDefaultCell(cellName); + if (code != 0) { + return code; + } + } -int -LogErrors (int level, const char *fmt, ...) -{ - va_list ap; + *avfpp = afscp_ResolvePath(fullPath); + if (*avfpp == NULL) { + if (afscp_errno == 0) + code = ENOENT; + else + code = afscp_errno; + } - va_start(ap, fmt); - return vfprintf(stderr, fmt, ap); -} + return code; +} /* GetVenusFidByPath */ -int +static int readFile(struct cmd_syndesc *as, void *unused) { - char *fname; - char *cell = 0; - afs_int32 code; - afs_int32 hosts[AFS_MAXHOSTS]; - AFSFid Fid; - int j; - struct rx_connection *RXConn; - struct cellLookup *cl; - struct rx_call *tcall; - struct AFSVolSync tsync; + char *fname = NULL; + char *cell = NULL; + char *realm = NULL; + afs_int32 code = 0; struct AFSFetchStatus OutStatus; - struct AFSCallBack CallBack; + struct afscp_venusfid *avfp = NULL; afs_int64 Pos; afs_int32 len; - afs_int64 length, Len; - u_char vnode = 0; - u_char first = 1; + afs_int64 length = 0, Len; int bytes; int worstCode = 0; char *buf = 0; + char ipv4_addr[16]; int bufflen = BUFFLEN; #ifdef AFS_NT40_ENV @@ -931,298 +580,265 @@ readFile(struct cmd_syndesc *as, void *unused) _setmode(1, _O_BINARY); #endif - if (as->name[0] == 'f') - vnode = 1; - if (as->parms[2].items) - verbose = 1; - if (as->parms[3].items) { - md5sum = 1; + gettimeofday(&starttime, &Timezone); + + CmdProlog(as, &cell, &realm, &fname, NULL); + afscp_AnonymousAuth(1); + + if (md5sum) MD5_Init(&md5); - } - CBServiceNeeded = 1; - InitializeCBService(); + if (realm != NULL) + code = afscp_SetDefaultRealm(realm); - gettimeofday (&starttime, NULL); - fname = as->parms[0].items->data; - cell = 0; - if (as->parms[1].items) - cell = as->parms[1].items->data; - if (vnode) - code = get_vnode_hosts(fname, &cell, hosts, &Fid, 1); + if (cell != NULL) + code = afscp_SetDefaultCell(cell); + + if (useFid) + code = GetVenusFidByFid(fname, cell, 0, &avfp); else - code = get_file_cell(fname, &cell, hosts, &Fid, &OutStatus, 0); - if (code) { - fprintf(stderr,"File not found %s\n", fname); - return code; + code = GetVenusFidByPath(fname, cell, &avfp); + if (code != 0) { + afs_com_err(pnp, code, "(file not found: %s)", fname); + return code; } - if (Fid.Vnode & 1) { - fprintf(stderr,"%s is a directory, not a file\n", fname); - return ENOENT; - } - cl = FindCell(cell); - for (j=0;jparms[6].items) { - afs_uint32 fields, ip1, ip2, ip3, ip4; - fields = sscanf(as->parms[6].items->data, "%d.%d.%d.%d", - &ip1, &ip2, &ip3, &ip4); - useHost = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4; - j--; - } else { - if (!hosts[j]) - break; - useHost = hosts[j]; - } - first = 0; - RXConn = FindRXConnection(useHost, htons(AFSCONF_FILEPORT), 1, - cl->sc, cl->scIndex); - if (!RXConn) { - fprintf(stderr,"rx_NewConnection failed to server 0x%X\n", - useHost); - continue; - } - code = AFS_FetchStatus(RXConn, &Fid, &OutStatus, &CallBack, &tsync); - if (code) { - fprintf(stderr,"RXAFS_FetchStatus failed to server 0x%X for" - " file %s, code was %d\n", - useHost, fname, code); - continue; - } - gettimeofday(&opentime, NULL); - if (verbose) { - seconds = (float)(opentime.tv_sec + opentime.tv_usec *.000001 - -starttime.tv_sec - starttime.tv_usec *.000001); - fprintf(stderr,"Startup to find the file took %.3f sec.\n", - seconds); - } - Len = OutStatus.Length_hi; - Len <<= 32; - Len += OutStatus.Length; - ZeroInt64(Pos); - { - afs_uint32 high, low; - - tcall = rx_NewCall(RXConn); - code = StartAFS_FetchData64 (tcall, &Fid, Pos, Len); - if (code == RXGEN_OPCODE) { - afs_int32 tmpPos, tmpLen; - tmpPos = (afs_int32)Pos; tmpLen = (afs_int32)Len; - code = StartAFS_FetchData (tcall, &Fid, tmpPos, tmpLen); - bytes = rx_Read(tcall, (char *)&low, sizeof(afs_int32)); - length = ntohl(low); - if (bytes != 4) code = -3; - } else if (!code) { - bytes = rx_Read(tcall, (char *)&high, 4); - length = ntohl(high); - length <<= 32; - bytes += rx_Read(tcall, (char *)&low, 4); - length += ntohl(low); - if (bytes != 8) code = -3; - } - if (code) { - if (code == RXGEN_OPCODE) { - fprintf(stderr, "File server for %s might not be running a" - " multi-resident AFS server\n", - fname); - } else { - fprintf(stderr, "%s for %s ended with error code %d\n", - (char *) &as->name, fname, code); - exit(1); - } - } - if (length > bufflen) - len = bufflen; - else - len = (afs_int32) length; - buf = (char *)malloc(len); - if (!buf) { - fprintf(stderr, "couldn't allocate buffer\n"); - exit(1); - } - while (!code && NonZeroInt64(length)) { - if (length > bufflen) - len = bufflen; - else - len = (afs_int32) length; - bytes = rx_Read(tcall, (char *) buf, len); - if (bytes != len) { - code = -3; - } - if (md5sum) - MD5_Update(&md5, buf, len); - if (!code) - write(1, buf, len); - length -= len; - xfered += len; - gettimeofday(&now, NULL); - if (verbose) - printDatarate(); - } - worstCode = code; - code = EndRXAFS_FetchData (tcall, &OutStatus, &CallBack, &tsync); - rx_EndCall(tcall, 0); - if (!worstCode) - worstCode = code; - } - break; + if (avfp->fid.Vnode & 1) { + code = ENOENT; + afs_com_err(pnp, code, "(%s is a directory, not a file)", fname); + afscp_FreeFid(avfp); + return code; } - gettimeofday(&readtime, NULL); - if (worstCode) { - fprintf(stderr,"%s failed with code %d\n", - (char *) &as->name, worstCode); - } else { - if (md5sum) { - afs_uint32 md5int[4]; - char *p; - MD5_Final((char *) &md5int[0], &md5); -#ifdef AFS_NT40_ENV - p = strrchr(fname,'\\'); -#else - p = strrchr(fname,'/'); -#endif - if (p) - p++; - else - p = fname; - fprintf(stderr, "%08x%08x%08x%08x %s\n", - htonl(md5int[0]), htonl(md5int[1]), - htonl(md5int[2]), htonl(md5int[3]), p); - } - if(verbose) { - seconds = (float)(readtime.tv_sec + readtime.tv_usec *.000001 - -opentime.tv_sec - opentime.tv_usec *.000001); - fprintf(stderr,"Transfer of %llu bytes took %.3f sec.\n", - xfered, seconds); - datarate = (xfered >> 20) / seconds; - fprintf(stderr,"Total data rate = %.03f MB/sec. for read\n", - datarate); - } + code = afscp_GetStatus(avfp, &OutStatus); + if (code != 0) { + afs_inet_ntoa_r(avfp->cell->fsservers[0]->addrs[0], ipv4_addr); + afs_com_err(pnp, code, "(failed to get status of file %s from" + "server %s, code = %d)", fname, ipv4_addr, code); + afscp_FreeFid(avfp); + return code; } - DestroyConnections(); + + gettimeofday(&opentime, &Timezone); + if (verbose) + fprintf(stderr, "Startup to find the file took %.3f sec.\n", + time_elapsed(&starttime, &opentime)); + Len = OutStatus.Length_hi; + Len <<= 32; + Len += OutStatus.Length; + ZeroInt64(Pos); + buf = (char *) malloc(bufflen * sizeof(char)); + if (buf == NULL) { + code = ENOMEM; + afs_com_err(pnp, code, "(cannot allocate buffer)"); + afscp_FreeFid(avfp); + return code; + } + memset(buf, 0, bufflen * sizeof(char)); + length = Len; + while (!code && NonZeroInt64(length)) { + if (length > bufflen) + len = bufflen; + else + len = (afs_int32) length; + bytes = afscp_PRead(avfp, buf, len, Pos); + if (bytes != len) + code = -3; /* what error name should we use here? */ + if (md5sum) + MD5_Update(&md5, buf, len); + if (code == 0) { + len = write(1, buf, len); /* to stdout */ + if (len == 0) + code = errno; + } + length -= len; + xfered += len; + if (verbose) + printDatarate(); + Pos += len; + worstCode = code; + } + afscp_FreeFid(avfp); + + gettimeofday(&readtime, &Timezone); + if (md5sum) + summarizeMD5(fname); + if (verbose) + summarizeDatarate(&readtime, "read"); + if (buf != NULL) + free(buf); + return worstCode; -} +} /* readFile */ -int +static int writeFile(struct cmd_syndesc *as, void *unused) { char *fname = NULL; - char *cell = 0; - afs_int32 code, localcode = 0; - afs_int32 hosts[AFS_MAXHOSTS]; - afs_uint32 useHost; - AFSFid Fid; - struct rx_connection *RXConn; - struct cellLookup *cl; - struct rx_call *tcall; - struct AFSVolSync tsync; + char *cell = NULL; + char *sSynthLen = NULL; + char *realm = NULL; + afs_int32 code = 0; + afs_int32 byteswritten; struct AFSFetchStatus OutStatus; struct AFSStoreStatus InStatus; - struct AFSCallBack CallBack; + struct afscp_venusfid *dirvfp = NULL, *newvfp = NULL; afs_int64 Pos; afs_int64 length, Len, synthlength = 0, offset = 0; - u_char vnode = 0; afs_int64 bytes; int worstCode = 0; - int append = 0; int synthesize = 0; - afs_int32 byteswritten; + int overWrite = 0; struct wbuf *bufchain = 0; struct wbuf *previous, *tbuf; + char dirName[AFSPATHMAX]; + char baseName[AFSNAMEMAX]; + char ipv4_addr[16]; #ifdef AFS_NT40_ENV /* stdin on Windows defaults to _O_TEXT mode */ _setmode(0, _O_BINARY); #endif - if (as->name[0] == 'f') { - vnode = 1; - if (as->name[3] == 'a') - append = 1; - } else - if (as->name[0] == 'a') - append = 1; - if (as->parms[2].items) - verbose = 1; - if (as->parms[3].items) - md5sum = 1; - if (as->parms[4].items) { - code = util_GetInt64(as->parms[4].items->data, &synthlength); - if (code) { - fprintf(stderr, "Invalid value for synthesize length %s\n", - as->parms[4].items->data); + CmdProlog(as, &cell, &realm, &fname, &sSynthLen); + afscp_AnonymousAuth(1); + + if (realm != NULL) + code = afscp_SetDefaultRealm(realm); + + if (cell != NULL) + code = afscp_SetDefaultCell(cell); + + if (sSynthLen) { + code = util_GetInt64(sSynthLen, &synthlength); + if (code != 0) { + afs_com_err(pnp, code, "(invalid value for synthesize length %s)", + sSynthLen); return code; } synthesize = 1; } - CBServiceNeeded = 1; - InitializeCBService(); - if (as->parms[0].items) - fname = as->parms[0].items->data; - - cell = 0; - if (as->parms[1].items) cell = as->parms[1].items->data; - if (vnode) { - code = get_vnode_hosts(fname, &cell, hosts, &Fid, 1); - if (code) + if (useFid) { + code = GetVenusFidByFid(fname, cell, 1, &newvfp); + if (code != 0) { + afs_com_err(pnp, code, "(GetVenusFidByFid returned code %d)", code); return code; - } else - code = get_file_cell(fname, &cell, hosts, &Fid, &OutStatus, append ? 0 : 1); - if (code) { - fprintf(stderr,"File or directory not found: %s\n", - fname); - return code; + } + } else { + code = GetVenusFidByPath(fname, cell, &newvfp); + if (code == 0) { /* file was found */ + if (force) + overWrite = 1; + else if (!append) { + /* + * file cannot already exist if specified by path and not + * appending to it unless user forces overwrite + */ + code = EEXIST; + afscp_FreeFid(newvfp); + afs_com_err(pnp, code, "(use -force to overwrite)"); + return code; + } + } else { /* file not found */ + if (append) { + code = ENOENT; + afs_com_err(pnp, code, "(cannot append to non-existent file)"); + return code; + } + } + if (!append && !overWrite) { /* must create a new file in this case */ + if ( BreakUpPath(fname, dirName, baseName) != 2 ) { + code = EINVAL; + afs_com_err(pnp, code, "(must provide full AFS path)"); + afscp_FreeFid(newvfp); + return code; + } + + code = GetVenusFidByPath(dirName, cell, &dirvfp); + afscp_FreeFid(newvfp); /* release now-unneeded fid */ + newvfp = NULL; + if (code != 0) { + afs_com_err(pnp, code, "(is dir %s in AFS?)", dirName); + return code; + } + } } - if (Fid.Vnode & 1) { - fprintf(stderr,"%s is a directory, not a file\n", fname); - return ENOENT; + + if ( (newvfp != NULL) && (newvfp->fid.Vnode & 1) ) { + code = EISDIR; + afs_com_err(pnp, code, "(%s is a directory, not a file)", fname); + afscp_FreeFid(newvfp); + afscp_FreeFid(dirvfp); + return code; } - if (!hosts[0]) { - fprintf(stderr,"AFS file not found: %s\n", fname); - return ENOENT; - } - cl = FindCell(cell); - gettimeofday (&starttime, NULL); - useHost = hosts[0]; - RXConn = FindRXConnection(useHost, htons(AFSCONF_FILEPORT), 1, - cl->sc, cl->scIndex); - if (!RXConn) { - fprintf(stderr,"rx_NewConnection failed to server 0x%X\n", - hosts[0]); - return -1; - } - code = AFS_FetchStatus(RXConn, &Fid, &OutStatus, &CallBack, &tsync); - if (code) { - fprintf(stderr,"RXAFS_FetchStatus failed to server 0x%X for file %s, code was%d\n", - useHost, fname, code); - return -1; - } - if (!append && (OutStatus.Length || OutStatus.Length_hi)) { - fprintf(stderr,"AFS file %s not empty, request aborted.\n", fname); - DestroyConnections(); - return -5; - } - InStatus.Mask = AFS_SETMODE + AFS_FSYNC; + gettimeofday(&starttime, &Timezone); + InStatus.UnixModeBits = 0644; + if (newvfp == NULL) { + code = afscp_CreateFile(dirvfp, baseName, &InStatus, &newvfp); + if (code != 0) { + afs_com_err(pnp, code, + "(could not create file %s in directory %lu.%lu.%lu)", + baseName, afs_printable_uint32_lu(dirvfp->fid.Volume), + afs_printable_uint32_lu(dirvfp->fid.Vnode), + afs_printable_uint32_lu(dirvfp->fid.Unique)); + return code; + } + } + code = afscp_GetStatus(newvfp, &OutStatus); + if (code != 0) { + afs_inet_ntoa_r(newvfp->cell->fsservers[0]->addrs[0], ipv4_addr); + afs_com_err(pnp, code, "(failed to get status of file %s from" + "server %s, code = %d)", fname, ipv4_addr, code); + afscp_FreeFid(newvfp); + afscp_FreeFid(dirvfp); + return code; + } + + if ( !append && !force && + (OutStatus.Length != 0 || OutStatus.Length_hi !=0 ) ) { + /* + * file exists, is of non-zero length, and we're not appending + * to it: user must force overwrite + * (covers fidwrite edge case) + */ + code = EEXIST; + afscp_FreeFid(newvfp); + afscp_FreeFid(dirvfp); + afs_com_err(pnp, code, "(use -force to overwrite)"); + return code; + } + + InStatus.Mask = AFS_SETMODE + AFS_FSYNC; if (append) { Pos = OutStatus.Length_hi; Pos = (Pos << 32) | OutStatus.Length; } else - Pos = 0; + Pos = 0; previous = (struct wbuf *)&bufchain; if (md5sum) MD5_Init(&md5); + /* + * currently, these two while loops (1) read the whole source file in + * before (2) writing any of it out, meaning that afsio can't deal with + * files larger than the maximum amount of memory designated for + * reading a file in (WRITEBUFLEN). + * Consider going to a single loop, like in readFile(), though will + * have implications on timing statistics (such as the "Startup to + * find the file" time, below). + */ Len = 0; - while (Len synthlength) l = synthlength; for (ll = 0; ll < l; ll += 4096) { - sprintf(&tbuf->buf[ll],"Offset (0x%x, 0x%x)\n", + sprintf(&tbuf->buf[ll], "Offset (0x%x, 0x%x)\n", (unsigned int)((offset + ll) >> 32), (unsigned int)((offset + ll) & 0xffffffff)); } offset += l; synthlength -= l; - tbuf->used = (afs_int32)l; + tbuf->used = (afs_int32) l; } else - tbuf->used = read(0, &tbuf->buf, tbuf->buflen); - if (!tbuf->used) { + tbuf->used = read(0, &tbuf->buf, tbuf->buflen); /* from stdin */ + if (tbuf->used == 0) { free(tbuf); break; } @@ -1252,231 +868,79 @@ writeFile(struct cmd_syndesc *as, void *unused) previous = tbuf; Len += tbuf->used; } - gettimeofday(&opentime, NULL); - if (verbose) { - seconds = (float) (opentime.tv_sec + opentime.tv_usec *.000001 - -starttime.tv_sec - starttime.tv_usec *.000001); - fprintf(stderr,"Startup to find the file took %.3f sec.\n", - seconds); - } + gettimeofday(&opentime, &Timezone); + if (verbose) + fprintf(stderr, "Startup to find the file took %.3f sec.\n", + time_elapsed(&starttime, &opentime)); bytes = Len; while (!code && bytes) { - afs_int32 code2; - Len = bytes; - restart: - tcall = rx_NewCall(RXConn); - code = StartAFS_StoreData64 (tcall, &Fid, &InStatus, Pos, Len, Pos+Len); - if (code == RXGEN_OPCODE) { - afs_uint32 tmpLen, tmpPos; - tmpPos = (afs_int32) Pos; - tmpLen = (afs_int32) Len; - if (Pos+Len > 0x7fffffff) { - fprintf(stderr,"AFS fileserver does not support files >= 2 GB\n"); - return EFBIG; - } - code = StartAFS_StoreData (tcall, &Fid, &InStatus, tmpPos, tmpLen, - tmpPos+tmpLen); - } - if (code) { - fprintf(stderr, "StartRXAFS_StoreData had error code %d\n", code); - return code; - } - length = Len; + Len = bytes; + length = Len; tbuf = bufchain; if (Len) { - for (tbuf= bufchain; tbuf; tbuf=tbuf->next) { - if (!tbuf->used) + for (tbuf = bufchain; tbuf; tbuf = tbuf->next) { + if (tbuf->used == 0) break; - byteswritten = rx_Write(tcall, tbuf->buf, tbuf->used); - if (byteswritten != tbuf->used) { + byteswritten = afscp_PWrite(newvfp, tbuf->buf, + tbuf->used, Pos + xfered); + if (byteswritten != tbuf->used) { fprintf(stderr,"Only %d instead of %" AFS_INT64_FMT " bytes transferred by rx_Write()\n", byteswritten, length); fprintf(stderr, "At %" AFS_UINT64_FMT " bytes from the end\n", length); - code = -4; + code = -4; break; - } + } xfered += tbuf->used; - gettimeofday(&now, NULL); - if (verbose) + if (verbose) printDatarate(); - length -= tbuf->used; - } - } - worstCode = code; - code = EndRXAFS_StoreData64 (tcall, &OutStatus, &tsync); - if (code) { - fprintf(stderr, "EndRXAFS_StoreData64 returned %d\n", code); - worstCode = code; - } - code2 = rx_Error(tcall); - if (code2) { - fprintf(stderr, "rx_Error returned %d\n", code2); - worstCode = code2; - } - code2 = rx_EndCall(tcall, localcode); - if (code2) { - fprintf(stderr, "rx_EndCall returned %d\n", code2); - worstCode = code2; - } - code = worstCode; - if (code == 110) { - fprintf(stderr, "Waiting for busy volume\n"); - sleep(10); - goto restart; + length -= tbuf->used; + } } Pos += Len; bytes = 0; if (!code) { - for (tbuf = bufchain; tbuf; tbuf=tbuf->next) { - tbuf->offset = 0; + for (tbuf = bufchain; tbuf; tbuf = tbuf->next) { + tbuf->offset = 0; if (synthesize) { - afs_int64 ll, l = tbuf->buflen; - if (l > synthlength) + afs_int64 ll, l = tbuf->buflen; + if (l > synthlength) l = synthlength; - for (ll = 0; ll < l; ll += 4096) { - sprintf(&tbuf->buf[ll],"Offset (0x%x, 0x%x)\n", + for (ll = 0; ll < l; ll += 4096) { + sprintf(&tbuf->buf[ll], "Offset (0x%x, 0x%x)\n", (unsigned int)((offset + ll) >> 32), (unsigned int)((offset + ll) & 0xffffffff)); - } - offset += l; - synthlength -= l; - tbuf->used = (afs_int32) l; + } + offset += l; + synthlength -= l; + tbuf->used = (afs_int32) l; } else - tbuf->used = read(0, &tbuf->buf, tbuf->buflen); - if (!tbuf->used) - break; + tbuf->used = read(0, &tbuf->buf, tbuf->buflen); /* from stdin */ + if (!tbuf->used) + break; if (md5sum) - MD5_Update(&md5, &tbuf->buf, tbuf->used); - Len += tbuf->used; + MD5_Update(&md5, &tbuf->buf, tbuf->used); + Len += tbuf->used; bytes += tbuf->used; - } - } + } + } } - gettimeofday(&writetime, NULL); - if (worstCode) { - fprintf(stderr,"%s failed with code %d\n", as->name, worstCode); - } else if(verbose) { - seconds = (float) (writetime.tv_sec + writetime.tv_usec *.000001 - -opentime.tv_sec - opentime.tv_usec *.000001); - fprintf(stderr,"Transfer of %llu bytes took %.3f sec.\n", - xfered, seconds); - datarate = (xfered >> 20) / seconds; - fprintf(stderr,"Total data rate = %.03f MB/sec. for write\n", - datarate); + afscp_FreeFid(newvfp); + afscp_FreeFid(dirvfp); + + gettimeofday(&writetime, &Timezone); + if (code) { + afs_com_err(pnp, code, "(%s failed with code %d)", as->name, + code); + } else if (verbose) { + summarizeDatarate(&writetime, "write"); } while (bufchain) { tbuf = bufchain; bufchain = tbuf->next; free(tbuf); } - DestroyConnections(); - if (md5sum) { - afs_uint32 md5int[4]; - char *p; - MD5_Final((char *) &md5int[0], &md5); -#ifdef AFS_NT40_ENV - p = strrchr(fname,'\\'); -#else - p = strrchr(fname,'/'); -#endif - if (p) - p++; - else - p = fname; - fprintf(stderr, "%08x%08x%08x%08x %s\n", - htonl(md5int[0]), htonl(md5int[1]), - htonl(md5int[2]), htonl(md5int[3]), p); - } + if (md5sum) + summarizeMD5(fname); + return worstCode; -} - -struct cellLookup * -FindCell(char *cellName) -{ - char name[MAXCELLCHARS]; - char *np; - struct cellLookup *p, *p2; - static struct afsconf_dir *tdir; - time_t expires; - afs_int32 len, code; - - if (cellName) { - np = cellName; - } else { - if (!tdir) - tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH); - len = MAXCELLCHARS; - afsconf_GetLocalCell(tdir, name, len); - np = (char *) &name; - } - SetCellFname(np); - - p2 = (struct cellLookup *) &Cells; - for (p = Cells; p; p = p->next) { - if (!strcmp((char *)&p->info.name, np)) { -#ifdef NO_AFS_CLIENT - if (!strcmp((char *)&lastcell, np)) - code = VLDBInit(1, &p->info); -#endif - return p; - } - p2 = p; - } - p2->next = (struct cellLookup *) malloc(sizeof(struct cellLookup)); - p = p2->next; - memset(p, 0, sizeof(struct cellLookup)); - p->next = (struct cellLookup *) 0; - if (!tdir) - tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH); - if (afsconf_GetCellInfo(tdir, np, AFSCONF_VLDBSERVICE, &p->info)) { - p2->next = (struct cellLookup *) 0; - free(p); - p = (struct cellLookup *) 0; - } else { -#ifdef NO_AFS_CLIENT - if (code = VLDBInit(1, &p->info)) - fprintf(stderr,"VLDBInit failed for cell %s\n", p->info.name); -#endif - code = afsconf_ClientAuthToken(&p->info, 0, &p->sc, &p->scIndex, &expires); - if (code) { - p->scIndex = RX_SECIDX_NULL; - p->sc = rxnull_NewClientSecurityObject(); - } - } - - if (p) - return p; - else - return 0; -} - -struct rx_connection * -FindRXConnection(afs_uint32 host, u_short port, u_short service, - struct rx_securityClass *securityObject, - int serviceSecurityIndex) -{ - int i; - - if (!ConnLookupInitialized) { - memset(ConnLookup, 0, MAX_HOSTS * sizeof(struct connectionLookup)); - ConnLookupInitialized = 1; - } - - for (i = 0; i < MAX_HOSTS; i++) { - if ((ConnLookup[i].host == host) && (ConnLookup[i].port == port)) - return ConnLookup[i].conn; - if (!ConnLookup[i].conn) - break; - } - - if (i >= MAX_HOSTS) - return 0; - - ConnLookup[i].conn = rx_NewConnection(host, port, service, securityObject, serviceSecurityIndex); - if (ConnLookup[i].conn) { - ConnLookup[i].host = host; - ConnLookup[i].port = port; - } - - return ConnLookup[i].conn; -} +} /* writeFile */