2 * Copyright (c) 2007, Hartmut Reuter,
3 * RZG, Max-Planck-Institut f. Plasmaphysik.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <afsconfig.h>
29 #include <afs/param.h>
34 #include <sys/types.h>
45 #include <afs/smb_iocons.h>
47 #include <afs/cm_ioctl.h>
48 #include <afs/pioctl_nt.h>
50 #include <sys/param.h>
52 #include <sys/ioctl.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
60 #include <afs/venus.h>
63 #include <afs/afsint.h>
64 #define FSINT_COMMON_XG 1
72 #include <afs/cellconfig.h>
73 #include <afs/afsutil.h>
76 #include <afs/afs_consts.h>
77 #include <afs/afscbint.h>
78 #include <afs/vldbint.h>
79 #include <afs/vlserver.h>
80 #include <afs/volser.h>
81 #include <afs/ptint.h>
84 #include <afs/ihandle.h>
85 #include <afs/vnode.h>
86 #include <afs/com_err.h>
94 #include <sys/malloc.h>
98 #include <afs/errors.h>
99 #include <afs/sys_prototypes.h>
100 #include <des_prototypes.h>
101 #include <rx_prototypes.h>
102 #include "../rxkad/md5.h"
104 #define afs_stat stat64
105 #define afs_fstat fstat64
106 #define afs_open open64
107 #else /* !O_LARGEFILE */
108 #define afs_stat stat
109 #define afs_fstat fstat
110 #define afs_open open
111 #endif /* !O_LARGEFILE */
112 #ifdef AFS_PTHREAD_ENV
114 pthread_key_t uclient_key;
117 int readFile(struct cmd_syndesc *as, void *);
118 int writeFile(struct cmd_syndesc *as, void *);
119 struct rx_connection *FindRXConnection(afs_uint32 host, u_short port, u_short service, struct rx_securityClass *securityObject, int serviceSecurityIndex);
120 struct cellLookup * FindCell(char *cellName);
124 static int verbose = 0; /* Set if -verbose option given */
125 static int CBServiceNeeded = 0;
126 static struct timeval starttime, opentime, readtime, writetime;
127 afs_uint64 xfered=0, oldxfered=0;
128 static struct timeval now;
129 struct timezone Timezone;
130 static float seconds, datarate, oldseconds;
131 extern int rxInitDone;
132 afs_uint64 transid = 0;
133 afs_uint32 expires = 0;
134 afs_uint32 server_List[MAXHOSTSPERCELL];
137 static struct ubik_client *uclient;
138 #define BUFFLEN 65536
139 #define WRITEBUFFLEN 1024*1024*64
147 afs_uint32 offset; /* offset inside the buffer */
148 afs_uint32 buflen; /* total length == BUFFLEN */
149 afs_uint32 used; /* bytes used inside buffer */
153 struct connectionLookup {
156 struct rx_connection *conn;
160 struct cellLookup *next;
161 struct afsconf_cell info;
162 struct rx_securityClass *sc;
167 struct dirLookup *next;
168 struct dirLookup *prev;
170 struct cellLookup *cell;
172 char name[VL_MAXNAMELEN];
175 struct cellLookup *Cells = 0;
176 struct dirLookup *Dirs = 0;
179 #define MAX_HOSTS 256
180 static struct connectionLookup ConnLookup[MAX_HOSTS];
181 static int ConnLookupInitialized = 0;
183 struct FsCmdInputs PioctlInputs;
184 struct FsCmdOutputs PioctlOutputs;
189 seconds = (float)(now.tv_sec + now.tv_usec *.000001
190 -opentime.tv_sec - opentime.tv_usec *.000001);
191 if ((seconds - oldseconds) > 30.) {
193 tmp = xfered - oldxfered;
194 datarate = ((afs_uint32) (tmp >> 20)) / (seconds - oldseconds);
195 fprintf(stderr,"%llu MB transferred, present date rate = %.0f MB/sec.\n",
196 xfered >> 20, datarate);
198 oldseconds = seconds;
203 SetCellFname(char *name)
205 struct afsconf_dir *tdir;
207 strcpy((char *) &cellFname,"/afs/");
209 strcat((char *) &cellFname, name);
211 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
212 afsconf_GetLocalCell(tdir, &cellFname[5], MAXCELLCHARS);
217 main (int argc, char **argv)
220 struct cmd_syndesc *ts;
222 strcpy(pnp, argv[0]);
224 #ifdef AFS_PTHREAD_ENV
225 assert(pthread_key_create(&uclient_key, NULL) == 0);
227 ts = cmd_CreateSyntax("read", readFile, CMD_REQUIRED,
228 "read a file from AFS");
229 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
230 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
231 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0);
232 cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
234 ts = cmd_CreateSyntax("fidread", readFile, CMD_REQUIRED,
235 "read on a non AFS-client a file from AFS");
236 cmd_IsAdministratorCommand(ts);
237 cmd_AddParm(ts, "-fid", CMD_SINGLE, CMD_REQUIRED, "volume.vnode.uniquifier");
238 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
239 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0);
240 cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
242 ts = cmd_CreateSyntax("write", writeFile, CMD_REQUIRED,
243 "write a file into AFS");
244 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "AFS-filename");
245 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
246 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0);
247 cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
248 cmd_AddParm(ts, "-synthesize", CMD_SINGLE, CMD_OPTIONAL, "create data pattern of specified length instead reading from stdin");
250 ts = cmd_CreateSyntax("fidwrite", writeFile, CMD_REQUIRED,
251 "write a file into AFS");
252 cmd_IsAdministratorCommand(ts);
253 cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED, "volume.vnode.uniquifier");
254 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
255 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0);
256 cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
258 ts = cmd_CreateSyntax("append", writeFile, CMD_REQUIRED,
259 "append to a file in AFS");
260 cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL, "AFS-filename");
261 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
262 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0);
264 ts = cmd_CreateSyntax("fidappend", writeFile, CMD_REQUIRED,
265 "append to a file in AFS");
266 cmd_IsAdministratorCommand(ts);
267 cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED, "volume.vnode.uniquifier");
268 cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
269 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *) 0);
271 code = cmd_Dispatch(argc, argv);
277 HandleLocalAuth(struct rx_securityClass **sc, afs_int32 *scIndex)
279 static struct afsconf_dir *tdir = NULL;
284 *scIndex = RX_SECIDX_NULL;
286 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
288 fprintf(stderr,"Could not open configuration directory: %s.\n",
289 AFSDIR_SERVER_ETC_DIRPATH);
292 code = afsconf_ClientAuth(tdir, sc, scIndex);
294 fprintf(stderr,"afsconf_ClientAuth returned %d\n", code);
301 AFS_Lookup(struct rx_connection *conn, AFSFid *dirfid, char *name,
302 AFSFid *outfid, AFSFetchStatus *outstatus, AFSFetchStatus
303 *dirstatus, AFSCallBack *callback, AFSVolSync *sync)
305 afs_int32 code = VBUSY;
306 while (code == VBUSY) {
307 code = RXAFS_Lookup(conn, dirfid, name, outfid, outstatus, dirstatus,
310 fprintf(stderr, "waiting for busy AFS volume %u.\n",
312 #ifdef AFS_PTHREAD_ENV
323 AFS_FetchStatus(struct rx_connection *conn, AFSFid *fid, AFSFetchStatus
324 *Status, AFSCallBack *callback, AFSVolSync *sync)
326 afs_int32 code = VBUSY;
328 while (code == VBUSY) {
329 code = RXAFS_FetchStatus(conn, fid, Status, callback, sync);
331 fprintf(stderr, "waiting for busy AFS volume %u.\n",
333 #ifdef AFS_PTHREAD_ENV
344 StartAFS_FetchData(struct rx_call *call, AFSFid *fid, afs_int32 pos,
347 afs_int32 code = VBUSY;
348 while (code == VBUSY) {
349 code = StartRXAFS_FetchData (call, fid, pos, len);
351 fprintf(stderr, "waiting for busy AFS volume %u.\n",
353 #ifdef AFS_PTHREAD_ENV
364 StartAFS_FetchData64(struct rx_call *call, AFSFid *fid, afs_int64 pos,
367 afs_int32 code = VBUSY;
368 while (code == VBUSY) {
369 code = StartRXAFS_FetchData64 (call, fid, pos, len);
371 fprintf(stderr, "waiting for busy AFS volume %u.\n",
373 #ifdef AFS_PTHREAD_ENV
384 StartAFS_StoreData(struct rx_call *call, AFSFid *fid, AFSStoreStatus *status,
385 afs_int32 pos, afs_int32 len, afs_int32 len2)
387 afs_int32 code = VBUSY;
388 while (code == VBUSY) {
389 code = StartRXAFS_StoreData (call, fid, status, pos, len, len2);
391 fprintf(stderr, "waiting for busy AFS volume %u.\n",
393 #ifdef AFS_PTHREAD_ENV
404 StartAFS_StoreData64(struct rx_call *call, AFSFid *fid, AFSStoreStatus *status,
405 afs_int64 pos, afs_int64 len, afs_int64 len2)
407 afs_int32 code = VBUSY;
408 while (code == VBUSY) {
409 code = StartRXAFS_StoreData64 (call, fid, status, pos, len, len2);
411 fprintf(stderr, "waiting for busy AFS volume %u.\n",
413 #ifdef AFS_PTHREAD_ENV
424 SRXAFSCB_CallBack(struct rx_call *rxcall, AFSCBFids *Fids_Array,
425 AFSCBs *CallBack_Array)
431 SRXAFSCB_InitCallBackState(struct rx_call *rxcall)
437 SRXAFSCB_Probe(struct rx_call *rxcall)
443 SRXAFSCB_GetCE(struct rx_call *rxcall,
445 AFSDBCacheEntry * ce)
451 SRXAFSCB_GetLock(struct rx_call *rxcall,
459 SRXAFSCB_XStatsVersion(struct rx_call *rxcall,
460 afs_int32 * versionNumberP)
466 SRXAFSCB_GetXStats(struct rx_call *rxcall,
467 afs_int32 clientVersionNumber,
468 afs_int32 collectionNumber,
469 afs_int32 * srvVersionNumberP,
471 AFSCB_CollData * dataP)
477 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid)
484 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
488 addr->numberOfInterfaces = 0;
491 /* return all network interface addresses */
492 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
493 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
494 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
495 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
496 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
504 SRXAFSCB_InitCallBackState2(struct rx_call *a_call, struct interfaceAddr *
511 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid)
517 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
518 afs_uint32 *serverVersion, afs_uint32 *configCount,
525 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
531 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
532 char **a_name, serverList *a_hosts)
538 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
539 afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank)
545 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call, struct interfaceAddr *
546 addr, Capabilities *capabilities)
552 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
553 char **a_name, serverList *a_hosts)
559 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
560 struct AFSDBCacheEntry64 *a_result)
566 InitializeCBService_LWP(void *unused)
568 struct rx_securityClass *CBsecobj;
569 struct rx_service *CBService;
571 afs_uuid_create(&uuid);
573 CBsecobj = (struct rx_securityClass *)rxnull_NewServerSecurityObject();
575 fprintf(stderr,"rxnull_NewServerSecurityObject failed for callback service.\n");
578 CBService = rx_NewService(0, 1, "afs", &CBsecobj, 1,
579 RXAFSCB_ExecuteRequest);
581 fprintf(stderr,"rx_NewService failed for callback service.\n");
590 InitializeCBService(void)
592 #define RESTOOL_CBPORT 7102
593 #define MAX_PORT_TRIES 1000
594 #define LWP_STACK_SIZE (16 * 1024)
596 #ifdef AFS_PTHREAD_ENV
597 pthread_t CBservicePid;
598 pthread_attr_t tattr;
600 PROCESS CBServiceLWP_ID, parentPid;
605 #ifndef NO_AFS_CLIENT
606 if (!CBServiceNeeded)
609 #ifndef AFS_PTHREAD_ENV
610 code = LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid);
611 if (code != LWP_SUCCESS) {
612 fprintf(stderr,"Unable to initialize LWP support, code %d\n",
618 #if defined(AFS_AIX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_DEC_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI_ENV)
620 InitialCBPort = RESTOOL_CBPORT + random() % 1000;
621 #else /* AFS_AIX_ENV || AFS_SUN_ENV || AFS_OSF_ENV || AFS_SGI_ENV */
622 #if defined(AFS_HPUX_ENV)
624 InitialCBPort = RESTOOL_CBPORT + lrand48() % 1000;
625 #else /* AFS_HPUX_ENV */
626 #if defined AFS_NT40_ENV
628 InitialCBPort = RESTOOL_CBPORT + rand() % 1000;
629 #else /* AFS_NT40_ENV */
631 InitialCBPort = RESTOOL_CBPORT + rand() % 1000;
632 #endif /* AFS_NT40_ENV */
633 #endif /* AFS_HPUX_ENV */
634 #endif /* AFS_AIX_ENV || AFS_SUN_ENV || AFS_OSF_ENV || AFS_SGI_ENV */
636 CBPort = InitialCBPort;
638 code = rx_Init(htons(CBPort));
640 if ((code == RX_ADDRINUSE) &&
641 (CBPort < MAX_PORT_TRIES + InitialCBPort)) {
643 } else if (CBPort < MAX_PORT_TRIES + InitialCBPort) {
644 fprintf(stderr, "rx_Init didn't succeed for callback service."
645 " Tried port numbers %d through %d\n",
646 InitialCBPort, CBPort);
649 fprintf(stderr,"Couldn't initialize callback service "
650 "because too many users are running this program. "
651 "Try again later.\n");
656 #ifdef AFS_PTHREAD_ENV
657 assert(pthread_attr_init(&tattr) == 0);
658 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
659 assert(pthread_create(
660 &CBservicePid, &tattr, InitializeCBService_LWP, 0)
663 code = LWP_CreateProcess(InitializeCBService_LWP, LWP_STACK_SIZE,
664 LWP_MAX_PRIORITY - 2, (int *) 0, "CBService",
666 if (code != LWP_SUCCESS) {
667 fprintf(stderr,"Unable to create the callback service LWP, code %d\n",
676 ScanVnode(char *fname, char *cell)
678 afs_int32 i, code = 0;
681 i = sscanf(fname, "%u.%u.%u",
682 &PioctlInputs.fid.Volume,
683 &PioctlInputs.fid.Vnode,
684 &PioctlInputs.fid.Unique);
686 PioctlInputs.fid.Volume = 0;
687 PioctlInputs.fid.Vnode = 0;
688 PioctlInputs.fid.Unique = 0;
689 fprintf(stderr,"fs: invalid vnode triple: %s\n", fname);
693 * The following is used to handle the case of unknown uniquifier. We
694 * just need a valid reference to the volume to direct the RPC to the
695 * right fileserver. Therefore we take the root directory of the volume.
697 if (PioctlInputs.fid.Unique == 0) {
698 PioctlInputs.int32s[0] = PioctlInputs.fid.Vnode;
699 PioctlInputs.fid.Vnode = 1;
700 PioctlInputs.fid.Unique = 1;
706 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
710 code = ugen_ClientInit(noAuthFlag, (char *) AFSDIR_CLIENT_ETC_DIRPATH,
711 info->name, 0, &uclient,
712 NULL, pnp, rxkad_clear,
713 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
714 0, 0, USER_SERVICE_ID);
720 get_vnode_hosts(char *fname, char **cellp, afs_int32 *hosts, AFSFid *Fid,
723 struct afsconf_dir *tdir;
724 struct vldbentry vldbEntry;
725 afs_int32 i, j, code, *h, len;
726 struct afsconf_cell info;
729 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
731 fprintf(stderr,"Could not process files in configuration directory "
732 "(%s).\n",AFSDIR_CLIENT_ETC_DIRPATH);
737 *cellp = (char *) malloc(MAXCELLCHARS);
738 code = afsconf_GetLocalCell(tdir, *cellp, len);
739 if (code) return code;
741 code = afsconf_GetCellInfo(tdir, *cellp, AFSCONF_VLDBSERVICE, &info);
743 fprintf(stderr,"fs: cell %s not in %s/CellServDB\n",
744 *cellp, AFSDIR_CLIENT_ETC_DIRPATH);
748 i = sscanf(fname, "%u.%u.%u", &Fid->Volume, &Fid->Vnode, &Fid->Unique);
750 fprintf(stderr,"fs: invalid vnode triple: %s\n", fname);
753 code = VLDBInit(1, &info);
755 code = ubik_VL_GetEntryByID(uclient, 0, Fid->Volume,
757 if (code == VL_NOENT)
758 fprintf(stderr,"fs: volume %u does not exist in this cell.\n",
760 if (code) return code;
764 if (!onlyRW) mask |= VLSF_RWVOL;
765 for (i=0, j=0; j<vldbEntry.nServers; j++) {
766 if (vldbEntry.serverFlags[j] & mask) {
767 *h++ = ntohl(vldbEntry.serverNumber[j]);
771 for (; i<AFS_MAXHOSTS; i++) *h++ = 0;
776 * Determine which AFS cell file 'fn' lives in, the list of servers that
777 * offer it, and the FID.
780 get_file_cell(char *fn, char **cellp, afs_int32 hosts[AFS_MAXHOSTS], AFSFid *Fid,
781 struct AFSFetchStatus *Status, afs_int32 create)
785 struct ViceIoctl status;
787 afs_int32 *Tmpafs_int32;
789 memset( Status, 0, sizeof(struct AFSFetchStatus));
790 memset(buf, 0, sizeof(buf));
792 status.out_size = sizeof(buf);
796 code = pioctl(fn, VIOC_FILE_CELL_NAME, &status, 0);
797 if (code && create) {
801 if ((c = strrchr(buf,'/'))) {
803 code = pioctl(buf,VIOC_FILE_CELL_NAME, &status, 0);
805 fd = open(fn, O_CREAT, 0644);
808 code = pioctl(fn, VIOC_FILE_CELL_NAME, &status, 0);
812 fprintf(stderr, "Unable to determine cell for %s\n", fn);
816 fprintf(stderr, "(File might not be in AFS)\n");
818 afs_com_err(pnp, code, (char *) 0);
820 *cellp = (char *) malloc(strlen(buf)+1);
822 SetCellFname(*cellp);
823 memset(buf, 0, sizeof(buf));
827 status.out_size = sizeof(buf);
828 code = pioctl(fn, VIOCWHEREIS, &status, 0);
830 fprintf(stderr, "Unable to determine fileservers for %s\n", fn);
835 afs_com_err(pnp, code, (char *) 0);
837 Tmpafs_int32 = (afs_int32 *)buf;
838 for (j=0;j<AFS_MAXHOSTS;++j) {
839 hosts[j] = Tmpafs_int32[j];
840 if (!Tmpafs_int32[j])
844 memset(buf, 0, sizeof(buf));
846 status.out_size = sizeof(buf);
849 code = pioctl(fn, VIOCGETFID, &status, 0);
851 fprintf(stderr, "Unable to determine FID for %s\n", fn);
855 afs_com_err(pnp, code, (char *) 0);
858 Tmpafs_int32 = (afs_int32 *)buf;
859 Fid->Volume = Tmpafs_int32[1];
860 Fid->Vnode = Tmpafs_int32[2];
861 Fid->Unique = Tmpafs_int32[3];
868 DestroyConnections(void)
872 if (!ConnLookupInitialized) return 0;
873 for (i = 0; i < MAX_HOSTS; i++) {
874 if (!ConnLookup[i].conn) break;
875 RXAFS_GiveUpAllCallBacks(ConnLookup[i].conn);
876 rx_DestroyConnection(ConnLookup[i].conn);
885 LogErrors (int level, const char *fmt, ...)
890 return vfprintf(stderr, fmt, ap);
894 readFile(struct cmd_syndesc *as, void *unused)
899 afs_int32 hosts[AFS_MAXHOSTS];
902 struct rx_connection *RXConn;
903 struct cellLookup *cl;
904 struct rx_call *tcall;
905 struct AFSVolSync tsync;
906 struct AFSFetchStatus OutStatus;
907 struct AFSCallBack CallBack;
910 afs_int64 length, Len;
916 int bufflen = BUFFLEN;
920 if (as->name[0] == 'f')
922 if (as->parms[2].items)
924 if (as->parms[3].items) {
930 InitializeCBService();
932 gettimeofday (&starttime, &Timezone);
933 fname = as->parms[0].items->data;
935 if (as->parms[1].items)
936 cell = as->parms[1].items->data;
938 code = get_vnode_hosts(fname, &cell, hosts, &Fid, 1);
940 code = get_file_cell(fname, &cell, hosts, &Fid, &OutStatus, 0);
942 fprintf(stderr,"File not found %s\n", fname);
946 fprintf(stderr,"%s is a directory, not a file\n", fname);
950 for (j=0;j<AFS_MAXHOSTS;++j) {
953 if (first && as->parms[6].items) {
954 afs_uint32 fields, ip1, ip2, ip3, ip4;
955 fields = sscanf(as->parms[6].items->data, "%d.%d.%d.%d",
956 &ip1, &ip2, &ip3, &ip4);
957 useHost = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4;
965 RXConn = FindRXConnection(useHost, htons(AFSCONF_FILEPORT), 1,
966 cl->sc, cl->scIndex);
968 fprintf(stderr,"rx_NewConnection failed to server 0x%X\n",
972 #ifndef NO_AFS_CLIENT
974 #endif /* NO_AFS_CLIENT */
975 code = AFS_FetchStatus(RXConn, &Fid, &OutStatus, &CallBack, &tsync);
977 fprintf(stderr,"RXAFS_FetchStatus failed to server 0x%X for"
978 " file %s, code was %d\n",
979 useHost, fname, code);
982 #ifndef NO_AFS_CLIENT
984 #endif /* NO_AFS_CLIENT */
985 gettimeofday(&opentime, &Timezone);
987 seconds = (float)(opentime.tv_sec + opentime.tv_usec *.000001
988 -starttime.tv_sec - starttime.tv_usec *.000001);
989 fprintf(stderr,"Startup to find the file took %.3f sec.\n",
992 Len = OutStatus.Length_hi;
994 Len += OutStatus.Length;
997 afs_uint32 high, low;
999 tcall = rx_NewCall(RXConn);
1000 code = StartAFS_FetchData64 (tcall, &Fid, Pos, Len);
1001 if (code == RXGEN_OPCODE) {
1002 afs_int32 tmpPos, tmpLen;
1003 tmpPos = (afs_int32)Pos; tmpLen = (afs_int32)Len;
1004 code = StartAFS_FetchData (tcall, &Fid, tmpPos, tmpLen);
1005 bytes = rx_Read(tcall, (char *)&low, sizeof(afs_int32));
1006 length = ntohl(low);
1007 if (bytes != 4) code = -3;
1009 bytes = rx_Read(tcall, (char *)&high, 4);
1010 length = ntohl(high);
1012 bytes += rx_Read(tcall, (char *)&low, 4);
1013 length += ntohl(low);
1014 if (bytes != 8) code = -3;
1017 if (code == RXGEN_OPCODE) {
1018 fprintf(stderr, "File server for %s might not be running a"
1019 " multi-resident AFS server\n",
1022 fprintf(stderr, "%s for %s ended with error code %d\n",
1023 (char *) &as->name, fname, code);
1027 if (length > bufflen)
1030 len = (afs_int32) length;
1031 buf = (char *)malloc(len);
1033 fprintf(stderr, "couldn't allocate buffer\n");
1036 while (!code && NonZeroInt64(length)) {
1037 if (length > bufflen)
1040 len = (afs_int32) length;
1041 bytes = rx_Read(tcall, (char *) buf, len);
1046 MD5_Update(&md5, buf, len);
1051 gettimeofday(&now, &Timezone);
1056 code = EndRXAFS_FetchData (tcall, &OutStatus, &CallBack, &tsync);
1057 rx_EndCall(tcall, 0);
1063 gettimeofday(&readtime, &Timezone);
1065 fprintf(stderr,"%s failed with code %d\n",
1066 (char *) &as->name, worstCode);
1069 afs_uint32 md5int[4];
1071 MD5_Final((char *) &md5int[0], &md5);
1072 p = fname + strlen(fname);
1074 if (*(--p) == '/') {
1079 fprintf(stderr, "%08x%08x%08x%08x %s\n",
1080 htonl(md5int[0]), htonl(md5int[1]),
1081 htonl(md5int[2]), htonl(md5int[3]), p);
1084 seconds = (float)(readtime.tv_sec + readtime.tv_usec *.000001
1085 -opentime.tv_sec - opentime.tv_usec *.000001);
1086 fprintf(stderr,"Transfer of %llu bytes took %.3f sec.\n",
1088 datarate = (xfered >> 20) / seconds;
1089 fprintf(stderr,"Total data rate = %.0f MB/sec. for read\n",
1093 DestroyConnections();
1098 writeFile(struct cmd_syndesc *as, void *unused)
1102 afs_int32 code, localcode = 0;
1103 afs_int32 hosts[AFS_MAXHOSTS];
1107 struct rx_connection *RXConn;
1108 struct cellLookup *cl;
1109 struct rx_call *tcall;
1110 struct AFSVolSync tsync;
1111 struct AFSFetchStatus OutStatus;
1112 struct AFSStoreStatus InStatus;
1113 struct AFSCallBack CallBack;
1115 afs_int64 length, Len, synthlength = 0, offset = 0;
1121 afs_int32 byteswritten;
1122 struct wbuf *bufchain = 0;
1123 struct wbuf *previous, *tbuf;
1127 if (as->name[0] == 'f') {
1129 if (as->name[3] == 'a')
1132 if (as->name[0] == 'a')
1134 if (as->parms[2].items)
1136 if (as->parms[3].items)
1138 if (as->parms[4].items) {
1139 code = util_GetInt64(as->parms[4].items->data, &synthlength);
1141 fprintf(stderr, "Invalid value for synthesize length %s\n",
1142 as->parms[4].items->data);
1147 CBServiceNeeded = 1;
1148 InitializeCBService();
1150 if (as->parms[0].items)
1151 fname = as->parms[0].items->data;
1154 if (as->parms[1].items) cell = as->parms[1].items->data;
1156 code = get_vnode_hosts(fname, &cell, hosts, &Fid, 1);
1160 code = get_file_cell(fname, &cell, hosts, &Fid, &OutStatus, append ? 0 : 1);
1162 fprintf(stderr,"File or directory not found: %s\n",
1166 if (Fid.Vnode & 1) {
1167 fprintf(stderr,"%s is a directory, not a file\n", fname);
1171 fprintf(stderr,"AFS file not found: %s\n", fname);
1174 cl = FindCell(cell);
1175 gettimeofday (&starttime, &Timezone);
1177 RXConn = FindRXConnection(useHost, htons(AFSCONF_FILEPORT), 1,
1178 cl->sc, cl->scIndex);
1180 fprintf(stderr,"rx_NewConnection failed to server 0x%X\n",
1184 code = AFS_FetchStatus(RXConn, &Fid, &OutStatus, &CallBack, &tsync);
1186 fprintf(stderr,"RXAFS_FetchStatus failed to server 0x%X for file %s, code was%d\n",
1187 useHost, fname, code);
1190 if (!append && (OutStatus.Length || OutStatus.Length_hi)) {
1191 fprintf(stderr,"AFS file %s not empty, request aborted.\n", fname);
1192 DestroyConnections();
1195 InStatus.Mask = AFS_SETMODE + AFS_FSYNC;
1196 InStatus.UnixModeBits = 0644;
1198 Pos = OutStatus.Length_hi;
1199 Pos = (Pos << 32) | OutStatus.Length;
1202 previous = (struct wbuf *)&bufchain;
1207 while (Len<WRITEBUFFLEN) {
1208 tbuf = (struct wbuf *)malloc(sizeof(struct wbuf));
1211 fprintf(stderr, "Couldn't allocate buffer, aborting\n");
1216 memset(tbuf, 0, sizeof(struct wbuf));
1217 tbuf->buflen = BUFFLEN;
1219 afs_int64 ll, l = tbuf->buflen;
1220 if (l > synthlength)
1222 for (ll = 0; ll < l; ll += 4096) {
1223 sprintf(&tbuf->buf[ll],"Offset (0x%x, 0x%x)\n",
1224 (unsigned int)((offset + ll) >> 32),
1225 (unsigned int)((offset + ll) & 0xffffffff));
1229 tbuf->used = (afs_int32)l;
1231 tbuf->used = read(0, &tbuf->buf, tbuf->buflen);
1237 MD5_Update(&md5, &tbuf->buf, tbuf->used);
1238 previous->next = tbuf;
1242 gettimeofday(&opentime, &Timezone);
1244 seconds = (float) (opentime.tv_sec + opentime.tv_usec *.000001
1245 -starttime.tv_sec - starttime.tv_usec *.000001);
1246 fprintf(stderr,"Startup to find the file took %.3f sec.\n",
1250 while (!code && bytes) {
1254 tcall = rx_NewCall(RXConn);
1255 code = StartAFS_StoreData64 (tcall, &Fid, &InStatus, Pos, Len, Pos+Len);
1256 if (code == RXGEN_OPCODE) {
1257 afs_uint32 tmpLen, tmpPos;
1258 tmpPos = (afs_int32) Pos;
1259 tmpLen = (afs_int32) Len;
1260 if (Pos+Len > 0x7fffffff) {
1261 fprintf(stderr,"AFS fileserver does not support files >= 2 GB\n");
1264 code = StartAFS_StoreData (tcall, &Fid, &InStatus, tmpPos, tmpLen,
1268 fprintf(stderr, "StartRXAFS_StoreData had error code %d\n", code);
1274 for (tbuf= bufchain; tbuf; tbuf=tbuf->next) {
1277 byteswritten = rx_Write(tcall, tbuf->buf, tbuf->used);
1278 if (byteswritten != tbuf->used) {
1279 fprintf(stderr,"Only %d instead of %" AFS_INT64_FMT " bytes transferred by rx_Write()\n", byteswritten, length);
1280 fprintf(stderr, "At %" AFS_UINT64_FMT " bytes from the end\n", length);
1284 xfered += tbuf->used;
1285 gettimeofday(&now, &Timezone);
1288 length -= tbuf->used;
1292 code = EndRXAFS_StoreData64 (tcall, &OutStatus, &tsync);
1294 fprintf(stderr, "EndRXAFS_StoreData64 returned %d\n", code);
1297 code2 = rx_Error(tcall);
1299 fprintf(stderr, "rx_Error returned %d\n", code2);
1302 code2 = rx_EndCall(tcall, localcode);
1304 fprintf(stderr, "rx_EndCall returned %d\n", code2);
1309 fprintf(stderr, "Waiting for busy volume\n");
1316 for (tbuf = bufchain; tbuf; tbuf=tbuf->next) {
1319 afs_int64 ll, l = tbuf->buflen;
1320 if (l > synthlength)
1322 for (ll = 0; ll < l; ll += 4096) {
1323 sprintf(&tbuf->buf[ll],"Offset (0x%x, 0x%x)\n",
1324 (unsigned int)((offset + ll) >> 32),
1325 (unsigned int)((offset + ll) & 0xffffffff));
1329 tbuf->used = (afs_int32) l;
1331 tbuf->used = read(0, &tbuf->buf, tbuf->buflen);
1335 MD5_Update(&md5, &tbuf->buf, tbuf->used);
1337 bytes += tbuf->used;
1341 gettimeofday(&writetime, &Timezone);
1343 fprintf(stderr,"%s failed with code %d\n", as->name, worstCode);
1344 } else if(verbose) {
1345 seconds = (float) (writetime.tv_sec + writetime.tv_usec *.000001
1346 -opentime.tv_sec - opentime.tv_usec *.000001);
1347 fprintf(stderr,"Transfer of %llu bytes took %.3f sec.\n",
1349 datarate = (xfered >> 20) / seconds;
1350 fprintf(stderr,"Total data rate = %.0f MB/sec. for write\n",
1355 bufchain = tbuf->next;
1358 DestroyConnections();
1360 afs_uint32 md5int[4];
1362 MD5_Final((char *) &md5int[0], &md5);
1363 p = fname + strlen(fname);
1365 if (*(--p) == '/') {
1370 fprintf(stdout, "%08x%08x%08x%08x %s\n",
1371 htonl(md5int[0]), htonl(md5int[1]),
1372 htonl(md5int[2]), htonl(md5int[3]), p);
1378 FindCell(char *cellName)
1380 char name[MAXCELLCHARS];
1382 struct cellLookup *p, *p2;
1383 static struct afsconf_dir *tdir;
1384 struct ktc_principal sname;
1385 struct ktc_token ttoken;
1387 afs_int32 len, code;
1393 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1395 afsconf_GetLocalCell(tdir, name, len);
1396 np = (char *) &name;
1400 p2 = (struct cellLookup *) &Cells;
1401 for (p = Cells; p; p = p->next) {
1402 if (!strcmp((char *)&p->info.name, np)) {
1403 #ifdef NO_AFS_CLIENT
1404 if (!strcmp((char *)&lastcell, np))
1405 code = VLDBInit(1, &p->info);
1411 p2->next = (struct cellLookup *) malloc(sizeof(struct cellLookup));
1413 memset(p, 0, sizeof(struct cellLookup));
1414 p->next = (struct cellLookup *) 0;
1416 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1417 if (afsconf_GetCellInfo(tdir, np, AFSCONF_VLDBSERVICE, &p->info)) {
1418 p2->next = (struct cellLookup *) 0;
1420 p = (struct cellLookup *) 0;
1422 #ifdef NO_AFS_CLIENT
1423 if (code = VLDBInit(1, &p->info))
1424 fprintf(stderr,"VLDBInit failed for cell %s\n", p->info.name);
1426 code = afsconf_ClientAuthToken(&p->info, 0, &p->sc, &p->scIndex, &expires);
1428 p->scIndex = RX_SECIDX_NULL;
1429 p->sc = rxnull_NewClientSecurityObject();
1439 struct rx_connection *
1440 FindRXConnection(afs_uint32 host, u_short port, u_short service,
1441 struct rx_securityClass *securityObject,
1442 int serviceSecurityIndex)
1446 if (!ConnLookupInitialized) {
1447 memset(ConnLookup, 0, MAX_HOSTS * sizeof(struct connectionLookup));
1448 ConnLookupInitialized = 1;
1451 for (i = 0; i < MAX_HOSTS; i++) {
1452 if ((ConnLookup[i].host == host) && (ConnLookup[i].port == port))
1453 return ConnLookup[i].conn;
1454 if (!ConnLookup[i].conn)
1461 ConnLookup[i].conn = rx_NewConnection(host, port, service, securityObject, serviceSecurityIndex);
1462 if (ConnLookup[i].conn) {
1463 ConnLookup[i].host = host;
1464 ConnLookup[i].port = port;
1467 return ConnLookup[i].conn;