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;
280 struct ktc_principal sname;
281 struct ktc_token ttoken;
283 struct ktc_encryptionKey key;
289 *scIndex = RX_SECIDX_NULL;
291 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
293 fprintf(stderr,"Could not open configuration directory: %s.\n",
294 AFSDIR_SERVER_ETC_DIRPATH);
297 code = afsconf_ClientAuth(tdir, sc, &scIndex);
299 fprintf(stderr,"afsconf_ClientAuth returned %d\n", code);
306 AFS_Lookup(struct rx_connection *conn, AFSFid *dirfid, char *name,
307 AFSFid *outfid, AFSFetchStatus *outstatus, AFSFetchStatus
308 *dirstatus, AFSCallBack *callback, AFSVolSync *sync)
310 afs_int32 code = VBUSY;
311 while (code == VBUSY) {
312 code = RXAFS_Lookup(conn, dirfid, name, outfid, outstatus, dirstatus,
315 fprintf(stderr, "waiting for busy AFS volume %u.\n",
317 #ifdef AFS_PTHREAD_ENV
328 AFS_FetchStatus(struct rx_connection *conn, AFSFid *fid, AFSFetchStatus
329 *Status, AFSCallBack *callback, AFSVolSync *sync)
331 afs_int32 code = VBUSY;
333 while (code == VBUSY) {
334 code = RXAFS_FetchStatus(conn, fid, Status, callback, sync);
336 fprintf(stderr, "waiting for busy AFS volume %u.\n",
338 #ifdef AFS_PTHREAD_ENV
349 StartAFS_FetchData(struct rx_call *call, AFSFid *fid, afs_int32 pos,
352 afs_int32 code = VBUSY;
353 while (code == VBUSY) {
354 code = StartRXAFS_FetchData (call, fid, pos, len);
356 fprintf(stderr, "waiting for busy AFS volume %u.\n",
358 #ifdef AFS_PTHREAD_ENV
369 StartAFS_FetchData64(struct rx_call *call, AFSFid *fid, afs_int64 pos,
372 afs_int32 code = VBUSY;
373 while (code == VBUSY) {
374 code = StartRXAFS_FetchData64 (call, fid, pos, len);
376 fprintf(stderr, "waiting for busy AFS volume %u.\n",
378 #ifdef AFS_PTHREAD_ENV
389 StartAFS_StoreData(struct rx_call *call, AFSFid *fid, AFSStoreStatus *status,
390 afs_int32 pos, afs_int32 len, afs_int32 len2)
392 afs_int32 code = VBUSY;
393 while (code == VBUSY) {
394 code = StartRXAFS_StoreData (call, fid, status, pos, len, len2);
396 fprintf(stderr, "waiting for busy AFS volume %u.\n",
398 #ifdef AFS_PTHREAD_ENV
409 StartAFS_StoreData64(struct rx_call *call, AFSFid *fid, AFSStoreStatus *status,
410 afs_int64 pos, afs_int64 len, afs_int64 len2)
412 afs_int32 code = VBUSY;
413 while (code == VBUSY) {
414 code = StartRXAFS_StoreData64 (call, fid, status, pos, len, len2);
416 fprintf(stderr, "waiting for busy AFS volume %u.\n",
418 #ifdef AFS_PTHREAD_ENV
429 SRXAFSCB_CallBack(struct rx_call *rxcall, AFSCBFids *Fids_Array,
430 AFSCBs *CallBack_Array)
436 SRXAFSCB_InitCallBackState(struct rx_call *rxcall)
442 SRXAFSCB_Probe(struct rx_call *rxcall)
448 SRXAFSCB_GetCE(struct rx_call *rxcall,
450 AFSDBCacheEntry * ce)
456 SRXAFSCB_GetLock(struct rx_call *rxcall,
464 SRXAFSCB_XStatsVersion(struct rx_call *rxcall,
465 afs_int32 * versionNumberP)
471 SRXAFSCB_GetXStats(struct rx_call *rxcall,
472 afs_int32 clientVersionNumber,
473 afs_int32 collectionNumber,
474 afs_int32 * srvVersionNumberP,
476 AFSCB_CollData * dataP)
482 SRXAFSCB_ProbeUuid(struct rx_call *a_call, afsUUID *a_uuid)
489 SRXAFSCB_WhoAreYou(struct rx_call *a_call, struct interfaceAddr *addr)
493 addr->numberOfInterfaces = 0;
496 /* return all network interface addresses */
497 addr->numberOfInterfaces = afs_cb_interface.numberOfInterfaces;
498 for ( i=0; i < afs_cb_interface.numberOfInterfaces; i++) {
499 addr->addr_in[i] = ntohl(afs_cb_interface.addr_in[i]);
500 addr->subnetmask[i] = ntohl(afs_cb_interface.subnetmask[i]);
501 addr->mtu[i] = ntohl(afs_cb_interface.mtu[i]);
509 SRXAFSCB_InitCallBackState2(struct rx_call *a_call, struct interfaceAddr *
516 SRXAFSCB_InitCallBackState3(struct rx_call *a_call, afsUUID *a_uuid)
522 SRXAFSCB_GetCacheConfig(struct rx_call *a_call, afs_uint32 callerVersion,
523 afs_uint32 *serverVersion, afs_uint32 *configCount,
530 SRXAFSCB_GetLocalCell(struct rx_call *a_call, char **a_name)
536 SRXAFSCB_GetCellServDB(struct rx_call *a_call, afs_int32 a_index,
537 char **a_name, serverList *a_hosts)
543 SRXAFSCB_GetServerPrefs(struct rx_call *a_call, afs_int32 a_index,
544 afs_int32 *a_srvr_addr, afs_int32 *a_srvr_rank)
550 SRXAFSCB_TellMeAboutYourself(struct rx_call *a_call, struct interfaceAddr *
551 addr, Capabilities *capabilities)
557 SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum,
558 char **a_name, serverList *a_hosts)
564 SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
565 struct AFSDBCacheEntry64 *a_result)
571 InitializeCBService_LWP(void *unused)
573 struct rx_securityClass *CBsecobj;
574 struct rx_service *CBService;
576 afs_uuid_create(&uuid);
578 CBsecobj = (struct rx_securityClass *)rxnull_NewServerSecurityObject();
580 fprintf(stderr,"rxnull_NewServerSecurityObject failed for callback service.\n");
583 CBService = rx_NewService(0, 1, "afs", &CBsecobj, 1,
584 RXAFSCB_ExecuteRequest);
586 fprintf(stderr,"rx_NewService failed for callback service.\n");
595 InitializeCBService(void)
597 #define RESTOOL_CBPORT 7102
598 #define MAX_PORT_TRIES 1000
599 #define LWP_STACK_SIZE (16 * 1024)
601 #ifdef AFS_PTHREAD_ENV
602 pthread_t CBservicePid;
603 pthread_attr_t tattr;
605 PROCESS CBServiceLWP_ID, parentPid;
610 #ifndef NO_AFS_CLIENT
611 if (!CBServiceNeeded)
614 #ifndef AFS_PTHREAD_ENV
615 code = LWP_InitializeProcessSupport(LWP_MAX_PRIORITY - 2, &parentPid);
616 if (code != LWP_SUCCESS) {
617 fprintf(stderr,"Unable to initialize LWP support, code %d\n",
623 #if defined(AFS_AIX_ENV) || defined(AFS_SUN_ENV) || defined(AFS_DEC_ENV) || defined(AFS_OSF_ENV) || defined(AFS_SGI_ENV)
625 InitialCBPort = RESTOOL_CBPORT + random() % 1000;
626 #else /* AFS_AIX_ENV || AFS_SUN_ENV || AFS_OSF_ENV || AFS_SGI_ENV */
627 #if defined(AFS_HPUX_ENV)
629 InitialCBPort = RESTOOL_CBPORT + lrand48() % 1000;
630 #else /* AFS_HPUX_ENV */
631 #if defined AFS_NT40_ENV
633 InitialCBPort = RESTOOL_CBPORT + rand() % 1000;
634 #else /* AFS_NT40_ENV */
636 InitialCBPort = RESTOOL_CBPORT + rand() % 1000;
637 #endif /* AFS_NT40_ENV */
638 #endif /* AFS_HPUX_ENV */
639 #endif /* AFS_AIX_ENV || AFS_SUN_ENV || AFS_OSF_ENV || AFS_SGI_ENV */
641 CBPort = InitialCBPort;
643 code = rx_Init(htons(CBPort));
645 if ((code == RX_ADDRINUSE) &&
646 (CBPort < MAX_PORT_TRIES + InitialCBPort)) {
648 } else if (CBPort < MAX_PORT_TRIES + InitialCBPort) {
649 fprintf(stderr, "rx_Init didn't succeed for callback service."
650 " Tried port numbers %d through %d\n",
651 InitialCBPort, CBPort);
654 fprintf(stderr,"Couldn't initialize callback service "
655 "because too many users are running this program. "
656 "Try again later.\n");
661 #ifdef AFS_PTHREAD_ENV
662 assert(pthread_attr_init(&tattr) == 0);
663 assert(pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED) == 0);
664 assert(pthread_create(
665 &CBservicePid, &tattr, InitializeCBService_LWP, 0)
668 code = LWP_CreateProcess(InitializeCBService_LWP, LWP_STACK_SIZE,
669 LWP_MAX_PRIORITY - 2, (int *) 0, "CBService",
671 if (code != LWP_SUCCESS) {
672 fprintf(stderr,"Unable to create the callback service LWP, code %d\n",
681 ScanVnode(char *fname, char *cell)
683 afs_int32 i, code = 0;
686 i = sscanf(fname, "%u.%u.%u",
687 &PioctlInputs.fid.Volume,
688 &PioctlInputs.fid.Vnode,
689 &PioctlInputs.fid.Unique);
691 PioctlInputs.fid.Volume = 0;
692 PioctlInputs.fid.Vnode = 0;
693 PioctlInputs.fid.Unique = 0;
694 fprintf(stderr,"fs: invalid vnode triple: %s\n", fname);
698 * The following is used to handle the case of unknown uniquifier. We
699 * just need a valid reference to the volume to direct the RPC to the
700 * right fileserver. Therefore we take the root directory of the volume.
702 if (PioctlInputs.fid.Unique == 0) {
703 PioctlInputs.int32s[0] = PioctlInputs.fid.Vnode;
704 PioctlInputs.fid.Vnode = 1;
705 PioctlInputs.fid.Unique = 1;
711 VLDBInit(int noAuthFlag, struct afsconf_cell *info)
715 code = ugen_ClientInit(noAuthFlag, (char *) AFSDIR_CLIENT_ETC_DIRPATH,
716 info->name, 0, &uclient,
717 NULL, pnp, rxkad_clear,
718 VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
719 0, 0, USER_SERVICE_ID);
725 get_vnode_hosts(char *fname, char **cellp, afs_int32 *hosts, AFSFid *Fid,
728 struct afsconf_dir *tdir;
729 struct vldbentry vldbEntry;
730 afs_int32 i, j, code, *h, len;
731 struct afsconf_cell info;
734 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
736 fprintf(stderr,"Could not process files in configuration directory "
737 "(%s).\n",AFSDIR_CLIENT_ETC_DIRPATH);
742 *cellp = (char *) malloc(MAXCELLCHARS);
743 code = afsconf_GetLocalCell(tdir, *cellp, len);
744 if (code) return code;
746 code = afsconf_GetCellInfo(tdir, *cellp, AFSCONF_VLDBSERVICE, &info);
748 fprintf(stderr,"fs: cell %s not in %s/CellServDB\n",
749 *cellp, AFSDIR_CLIENT_ETC_DIRPATH);
753 i = sscanf(fname, "%u.%u.%u", &Fid->Volume, &Fid->Vnode, &Fid->Unique);
755 fprintf(stderr,"fs: invalid vnode triple: %s\n", fname);
758 code = VLDBInit(1, &info);
760 code = ubik_VL_GetEntryByID(uclient, 0, Fid->Volume,
762 if (code == VL_NOENT)
763 fprintf(stderr,"fs: volume %u does not exist in this cell.\n",
765 if (code) return code;
769 if (!onlyRW) mask |= VLSF_RWVOL;
770 for (i=0, j=0; j<vldbEntry.nServers; j++) {
771 if (vldbEntry.serverFlags[j] & mask) {
772 *h++ = ntohl(vldbEntry.serverNumber[j]);
776 for (; i<AFS_MAXHOSTS; i++) *h++ = 0;
781 * Determine which AFS cell file 'fn' lives in, the list of servers that
782 * offer it, and the FID.
785 get_file_cell(char *fn, char **cellp, afs_int32 hosts[AFS_MAXHOSTS], AFSFid *Fid,
786 struct AFSFetchStatus *Status, afs_int32 create)
790 struct ViceIoctl status;
792 afs_int32 *Tmpafs_int32;
794 memset( Status, 0, sizeof(struct AFSFetchStatus));
795 memset(buf, 0, sizeof(buf));
797 status.out_size = sizeof(buf);
801 code = pioctl(fn, VIOC_FILE_CELL_NAME, &status, 0);
802 if (code && create) {
806 if ((c = strrchr(buf,'/'))) {
808 code = pioctl(buf,VIOC_FILE_CELL_NAME, &status, 0);
810 fd = open(fn, O_CREAT, 0644);
813 code = pioctl(fn, VIOC_FILE_CELL_NAME, &status, 0);
817 fprintf(stderr, "Unable to determine cell for %s\n", fn);
821 fprintf(stderr, "(File might not be in AFS)\n");
823 afs_com_err(pnp, code, (char *) 0);
825 *cellp = (char *) malloc(strlen(buf)+1);
827 SetCellFname(*cellp);
828 memset(buf, 0, sizeof(buf));
832 status.out_size = sizeof(buf);
833 code = pioctl(fn, VIOCWHEREIS, &status, 0);
835 fprintf(stderr, "Unable to determine fileservers for %s\n", fn);
840 afs_com_err(pnp, code, (char *) 0);
842 Tmpafs_int32 = (afs_int32 *)buf;
843 for (j=0;j<AFS_MAXHOSTS;++j) {
844 hosts[j] = Tmpafs_int32[j];
845 if (!Tmpafs_int32[j])
849 memset(buf, 0, sizeof(buf));
851 status.out_size = sizeof(buf);
854 code = pioctl(fn, VIOCGETFID, &status, 0);
856 fprintf(stderr, "Unable to determine FID for %s\n", fn);
860 afs_com_err(pnp, code, (char *) 0);
863 Tmpafs_int32 = (afs_int32 *)buf;
864 Fid->Volume = Tmpafs_int32[1];
865 Fid->Vnode = Tmpafs_int32[2];
866 Fid->Unique = Tmpafs_int32[3];
873 DestroyConnections(void)
877 if (!ConnLookupInitialized) return 0;
878 for (i = 0; i < MAX_HOSTS; i++) {
879 if (!ConnLookup[i].conn) break;
880 RXAFS_GiveUpAllCallBacks(ConnLookup[i].conn);
881 rx_DestroyConnection(ConnLookup[i].conn);
890 LogErrors (int level, const char *fmt, ...)
895 return vfprintf(stderr, fmt, ap);
899 readFile(struct cmd_syndesc *as, void *unused)
904 afs_int32 hosts[AFS_MAXHOSTS];
907 struct rx_connection *RXConn;
908 struct cellLookup *cl;
909 struct rx_call *tcall;
910 struct AFSVolSync tsync;
911 struct AFSFetchStatus OutStatus;
912 struct AFSCallBack CallBack;
915 afs_int64 length, Len;
921 int bufflen = BUFFLEN;
925 if (as->name[0] == 'f')
927 if (as->parms[2].items)
929 if (as->parms[3].items) {
935 InitializeCBService();
937 gettimeofday (&starttime, &Timezone);
938 fname = as->parms[0].items->data;
940 if (as->parms[1].items)
941 cell = as->parms[1].items->data;
943 code = get_vnode_hosts(fname, &cell, hosts, &Fid, 1);
945 code = get_file_cell(fname, &cell, hosts, &Fid, &OutStatus, 0);
947 fprintf(stderr,"File not found %s\n", fname);
951 fprintf(stderr,"%s is a directory, not a file\n", fname);
955 for (j=0;j<AFS_MAXHOSTS;++j) {
958 if (first && as->parms[6].items) {
959 afs_uint32 fields, ip1, ip2, ip3, ip4;
960 fields = sscanf(as->parms[6].items->data, "%d.%d.%d.%d",
961 &ip1, &ip2, &ip3, &ip4);
962 useHost = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4;
970 RXConn = FindRXConnection(useHost, htons(AFSCONF_FILEPORT), 1,
971 cl->sc, cl->scIndex);
973 fprintf(stderr,"rx_NewConnection failed to server 0x%X\n",
977 #ifndef NO_AFS_CLIENT
979 #endif /* NO_AFS_CLIENT */
980 code = AFS_FetchStatus(RXConn, &Fid, &OutStatus, &CallBack, &tsync);
982 fprintf(stderr,"RXAFS_FetchStatus failed to server 0x%X for"
983 " file %s, code was %d\n",
984 useHost, fname, code);
987 #ifndef NO_AFS_CLIENT
989 #endif /* NO_AFS_CLIENT */
990 gettimeofday(&opentime, &Timezone);
992 seconds = (float)(opentime.tv_sec + opentime.tv_usec *.000001
993 -starttime.tv_sec - starttime.tv_usec *.000001);
994 fprintf(stderr,"Startup to find the file took %.3f sec.\n",
997 Len = OutStatus.Length_hi;
999 Len += OutStatus.Length;
1002 afs_uint32 high, low;
1004 tcall = rx_NewCall(RXConn);
1005 code = StartAFS_FetchData64 (tcall, &Fid, Pos, Len);
1006 if (code == RXGEN_OPCODE) {
1007 afs_int32 tmpPos, tmpLen;
1008 tmpPos = (afs_int32)Pos; tmpLen = (afs_int32)Len;
1009 code = StartAFS_FetchData (tcall, &Fid, tmpPos, tmpLen);
1010 bytes = rx_Read(tcall, (char *)&low, sizeof(afs_int32));
1011 length = ntohl(low);
1012 if (bytes != 4) code = -3;
1014 bytes = rx_Read(tcall, (char *)&high, 4);
1015 length = ntohl(high);
1017 bytes += rx_Read(tcall, (char *)&low, 4);
1018 length += ntohl(low);
1019 if (bytes != 8) code = -3;
1022 if (code == RXGEN_OPCODE) {
1023 fprintf(stderr, "File server for %s might not be running a"
1024 " multi-resident AFS server\n",
1027 fprintf(stderr, "%s for %s ended with error code %d\n",
1028 (char *) &as->name, fname, code);
1032 if (length > bufflen)
1035 len = (afs_int32) length;
1036 buf = (char *)malloc(len);
1038 fprintf(stderr, "couldn't allocate buffer\n");
1041 while (!code && NonZeroInt64(length)) {
1042 if (length > bufflen)
1045 len = (afs_int32) length;
1046 bytes = rx_Read(tcall, (char *) buf, len);
1051 MD5_Update(&md5, buf, len);
1056 gettimeofday(&now, &Timezone);
1061 code = EndRXAFS_FetchData (tcall, &OutStatus, &CallBack, &tsync);
1062 rx_EndCall(tcall, 0);
1068 gettimeofday(&readtime, &Timezone);
1070 fprintf(stderr,"%s failed with code %d\n",
1071 (char *) &as->name, worstCode);
1074 afs_uint32 md5int[4];
1076 MD5_Final((char *) &md5int[0], &md5);
1077 p = fname + strlen(fname);
1079 if (*(--p) == '/') {
1084 fprintf(stderr, "%08x%08x%08x%08x %s\n",
1085 htonl(md5int[0]), htonl(md5int[1]),
1086 htonl(md5int[2]), htonl(md5int[3]), p);
1089 seconds = (float)(readtime.tv_sec + readtime.tv_usec *.000001
1090 -opentime.tv_sec - opentime.tv_usec *.000001);
1091 fprintf(stderr,"Transfer of %llu bytes took %.3f sec.\n",
1093 datarate = (xfered >> 20) / seconds;
1094 fprintf(stderr,"Total data rate = %.0f MB/sec. for read\n",
1098 DestroyConnections();
1103 writeFile(struct cmd_syndesc *as, void *unused)
1107 afs_int32 code, localcode = 0;
1108 afs_int32 hosts[AFS_MAXHOSTS];
1112 struct rx_connection *RXConn;
1113 struct cellLookup *cl;
1114 struct rx_call *tcall;
1115 struct AFSVolSync tsync;
1116 struct AFSFetchStatus OutStatus;
1117 struct AFSStoreStatus InStatus;
1118 struct AFSCallBack CallBack;
1120 afs_int64 length, Len, synthlength = 0, offset = 0;
1126 afs_int32 byteswritten;
1127 struct wbuf *bufchain = 0;
1128 struct wbuf *previous, *tbuf;
1132 if (as->name[0] == 'f') {
1134 if (as->name[3] == 'a')
1137 if (as->name[0] == 'a')
1139 if (as->parms[2].items)
1141 if (as->parms[3].items)
1143 if (as->parms[4].items) {
1144 code = util_GetInt64(as->parms[4].items->data, &synthlength);
1146 fprintf(stderr, "Invalid value for synthesize length %s\n",
1147 as->parms[4].items->data);
1152 CBServiceNeeded = 1;
1153 InitializeCBService();
1155 if (as->parms[0].items)
1156 fname = as->parms[0].items->data;
1159 if (as->parms[1].items) cell = as->parms[1].items->data;
1161 code = get_vnode_hosts(fname, &cell, hosts, &Fid, 1);
1165 code = get_file_cell(fname, &cell, hosts, &Fid, &OutStatus, append ? 0 : 1);
1167 fprintf(stderr,"File or directory not found: %s\n",
1171 if (Fid.Vnode & 1) {
1172 fprintf(stderr,"%s is a directory, not a file\n", fname);
1176 fprintf(stderr,"AFS file not found: %s\n", fname);
1179 cl = FindCell(cell);
1180 gettimeofday (&starttime, &Timezone);
1182 RXConn = FindRXConnection(useHost, htons(AFSCONF_FILEPORT), 1,
1183 cl->sc, cl->scIndex);
1185 fprintf(stderr,"rx_NewConnection failed to server 0x%X\n",
1189 code = AFS_FetchStatus(RXConn, &Fid, &OutStatus, &CallBack, &tsync);
1191 fprintf(stderr,"RXAFS_FetchStatus failed to server 0x%X for file %s, code was%d\n",
1192 useHost, fname, code);
1195 if (!append && (OutStatus.Length || OutStatus.Length_hi)) {
1196 fprintf(stderr,"AFS file %s not empty, request aborted.\n", fname);
1197 DestroyConnections();
1200 InStatus.Mask = AFS_SETMODE + AFS_FSYNC;
1201 InStatus.UnixModeBits = 0644;
1203 Pos = OutStatus.Length_hi;
1204 Pos = (Pos << 32) | OutStatus.Length;
1207 previous = (struct wbuf *)&bufchain;
1212 while (Len<WRITEBUFFLEN) {
1213 tbuf = (struct wbuf *)malloc(sizeof(struct wbuf));
1216 fprintf(stderr, "Couldn't allocate buffer, aborting\n");
1221 memset(tbuf, 0, sizeof(struct wbuf));
1222 tbuf->buflen = BUFFLEN;
1224 afs_int64 ll, l = tbuf->buflen;
1225 if (l > synthlength)
1227 for (ll = 0; ll < l; ll += 4096) {
1228 sprintf(&tbuf->buf[ll],"Offset (0x%x, 0x%x)\n",
1229 (unsigned int)((offset + ll) >> 32),
1230 (unsigned int)((offset + ll) & 0xffffffff));
1234 tbuf->used = (afs_int32)l;
1236 tbuf->used = read(0, &tbuf->buf, tbuf->buflen);
1242 MD5_Update(&md5, &tbuf->buf, tbuf->used);
1243 previous->next = tbuf;
1247 gettimeofday(&opentime, &Timezone);
1249 seconds = (float) (opentime.tv_sec + opentime.tv_usec *.000001
1250 -starttime.tv_sec - starttime.tv_usec *.000001);
1251 fprintf(stderr,"Startup to find the file took %.3f sec.\n",
1255 while (!code && bytes) {
1259 tcall = rx_NewCall(RXConn);
1260 code = StartAFS_StoreData64 (tcall, &Fid, &InStatus, Pos, Len, Pos+Len);
1261 if (code == RXGEN_OPCODE) {
1262 afs_uint32 tmpLen, tmpPos;
1263 tmpPos = (afs_int32) Pos;
1264 tmpLen = (afs_int32) Len;
1265 if (Pos+Len > 0x7fffffff) {
1266 fprintf(stderr,"AFS fileserver does not support files >= 2 GB\n");
1269 code = StartAFS_StoreData (tcall, &Fid, &InStatus, tmpPos, tmpLen,
1273 fprintf(stderr, "StartRXAFS_StoreData had error code %d\n", code);
1279 for (tbuf= bufchain; tbuf; tbuf=tbuf->next) {
1282 byteswritten = rx_Write(tcall, tbuf->buf, tbuf->used);
1283 if (byteswritten != tbuf->used) {
1284 fprintf(stderr,"Only %d instead of %" AFS_INT64_FMT " bytes transferred by rx_Write()\n", byteswritten, length);
1285 fprintf(stderr, "At %" AFS_UINT64_FMT " bytes from the end\n", length);
1289 xfered += tbuf->used;
1290 gettimeofday(&now, &Timezone);
1293 length -= tbuf->used;
1297 code = EndRXAFS_StoreData64 (tcall, &OutStatus, &tsync);
1299 fprintf(stderr, "EndRXAFS_StoreData64 returned %d\n", code);
1302 code2 = rx_Error(tcall);
1304 fprintf(stderr, "rx_Error returned %d\n", code2);
1307 code2 = rx_EndCall(tcall, localcode);
1309 fprintf(stderr, "rx_EndCall returned %d\n", code2);
1314 fprintf(stderr, "Waiting for busy volume\n");
1321 for (tbuf = bufchain; tbuf; tbuf=tbuf->next) {
1324 afs_int64 ll, l = tbuf->buflen;
1325 if (l > synthlength)
1327 for (ll = 0; ll < l; ll += 4096) {
1328 sprintf(&tbuf->buf[ll],"Offset (0x%x, 0x%x)\n",
1329 (unsigned int)((offset + ll) >> 32),
1330 (unsigned int)((offset + ll) & 0xffffffff));
1334 tbuf->used = (afs_int32) l;
1336 tbuf->used = read(0, &tbuf->buf, tbuf->buflen);
1340 MD5_Update(&md5, &tbuf->buf, tbuf->used);
1342 bytes += tbuf->used;
1346 gettimeofday(&writetime, &Timezone);
1348 fprintf(stderr,"%s failed with code %d\n", as->name, worstCode);
1349 } else if(verbose) {
1350 seconds = (float) (writetime.tv_sec + writetime.tv_usec *.000001
1351 -opentime.tv_sec - opentime.tv_usec *.000001);
1352 fprintf(stderr,"Transfer of %llu bytes took %.3f sec.\n",
1354 datarate = (xfered >> 20) / seconds;
1355 fprintf(stderr,"Total data rate = %.0f MB/sec. for write\n",
1360 bufchain = tbuf->next;
1363 DestroyConnections();
1365 afs_uint32 md5int[4];
1367 MD5_Final((char *) &md5int[0], &md5);
1368 p = fname + strlen(fname);
1370 if (*(--p) == '/') {
1375 fprintf(stdout, "%08x%08x%08x%08x %s\n",
1376 htonl(md5int[0]), htonl(md5int[1]),
1377 htonl(md5int[2]), htonl(md5int[3]), p);
1383 FindCell(char *cellName)
1385 char name[MAXCELLCHARS];
1387 struct cellLookup *p, *p2;
1388 static struct afsconf_dir *tdir;
1389 struct ktc_principal sname;
1390 struct ktc_token ttoken;
1391 afs_int32 len, code;
1397 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1399 afsconf_GetLocalCell(tdir, name, len);
1400 np = (char *) &name;
1404 p2 = (struct cellLookup *) &Cells;
1405 for (p = Cells; p; p = p->next) {
1406 if (!strcmp((char *)&p->info.name, np)) {
1407 #ifdef NO_AFS_CLIENT
1408 if (!strcmp((char *)&lastcell, np))
1409 code = VLDBInit(1, &p->info);
1415 p2->next = (struct cellLookup *) malloc(sizeof(struct cellLookup));
1417 memset(p, 0, sizeof(struct cellLookup));
1418 p->next = (struct cellLookup *) 0;
1420 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1421 if (afsconf_GetCellInfo(tdir, np, AFSCONF_VLDBSERVICE, &p->info)) {
1422 p2->next = (struct cellLookup *) 0;
1424 p = (struct cellLookup *) 0;
1426 #ifdef NO_AFS_CLIENT
1427 if (code = VLDBInit(1, &p->info))
1428 fprintf(stderr,"VLDBInit failed for cell %s\n", p->info.name);
1430 code = afsconf_ClientAuthToken(&p->info, 0, &p->sc, &p->scIndex);
1432 p->scIndex = RX_SECIDX_NULL;
1433 p->sc = rxnull_NewClientSecurityObject();
1443 struct rx_connection *
1444 FindRXConnection(afs_uint32 host, u_short port, u_short service,
1445 struct rx_securityClass *securityObject,
1446 int serviceSecurityIndex)
1450 if (!ConnLookupInitialized) {
1451 memset(ConnLookup, 0, MAX_HOSTS * sizeof(struct connectionLookup));
1452 ConnLookupInitialized = 1;
1455 for (i = 0; i < MAX_HOSTS; i++) {
1456 if ((ConnLookup[i].host == host) && (ConnLookup[i].port == port))
1457 return ConnLookup[i].conn;
1458 if (!ConnLookup[i].conn)
1465 ConnLookup[i].conn = rx_NewConnection(host, port, service, securityObject, serviceSecurityIndex);
1466 if (ConnLookup[i].conn) {
1467 ConnLookup[i].host = host;
1468 ConnLookup[i].port = port;
1471 return ConnLookup[i].conn;