5 #include <sys/socket.h>
6 #include <netinet/in.h>
10 #include <sys/select.h>
13 #include <afs/param.h>
14 #include <afs/afsint.h>
15 #include <sys/ioctl.h>
16 #include <afs/venus.h>
17 #include <afs/cellconfig.h>
20 /*#include <rx/rxkad.h>*/
21 #include <rx/rx_null.h>
31 int statfile(char *path, char *cellname, afs_uint32 *server,
37 afs_int32 srvbuf[MAXHOSTS];
43 v.out_size=MAXCELLCHARS;
44 if ((code=pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
48 v.out_size=sizeof(struct VenusFid);
49 if ((code=pioctl(path, VIOCGETFID, &v, 1)))
51 memcpy(f,&vf.Fid, sizeof(struct AFSFid));
54 v.out_size=sizeof(srvbuf);
55 if ((code=pioctl(path, VIOCWHEREIS, &v, 1)))
57 if (v.out_size <= sizeof(afs_int32))
60 memcpy(server, srvbuf, sizeof(afs_int32));
65 extern int RXAFSCB_ExecuteRequest();
66 struct rx_securityClass *sc;
68 extern int start_cb_server()
72 sc=rxnull_NewServerSecurityObject();
73 s=rx_NewService(0,1,"afs", &sc, 1, RXAFSCB_ExecuteRequest);
81 /*extern int rx_socket;*/
82 extern unsigned short rx_port;
89 fprintf(stderr, "Cannot initialize rx\n");
93 len=sizeof(struct sockaddr_in);
94 if (getsockname(rx_socket, &s, &len)) {
95 perror("getsockname");
98 rx_port=ntohs(s.sin_port);
103 struct rx_securityClass *get_sc(char * cellname)
106 char realm[REALM_SZ];
110 return rxnull_NewClientSecurityObject();
113 ucstring(realm, cellname, REALM_SZ);
115 if (krb_get_cred("afs", "", realm, &c)) {
116 if (get_ad_tkt("afs","",realm, DEFAULT_TKT_LIFE)) {
119 if (krb_get_cred("afs", "", realm, &c)) {
125 return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno,
126 c.ticket_st.length, c.ticket_st.dat);
130 #define scindex_NULL 0
131 #define scindex_RXKAD 2
133 #define scindex scindex_RXKAD
134 int main(int argc, char **argv)
136 char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
137 afs_uint32 ssrv, dsrv;
138 char *databuffer,*srcf,*destd,*destf,*destpath;
141 struct AFSStoreStatus sst;
142 struct AFSFetchStatus fst,dfst;
143 struct AFSVolSync vs;
144 struct AFSCallBack scb,dcb;
145 struct AFSFid sf, dd, df;
148 int ch, blksize, bytesremaining, bytes;
149 struct timeval start, finish;
151 struct rx_securityClass *ssc = 0, *dsc = 0;
152 int sscindex, dscindex;
153 struct rx_connection *sconn,*dconn;
154 struct rx_call *scall, *dcall;
155 int code,fetchcode,storecode,printcallerrs;
156 int slcl = 0, dlcl = 0;
157 int sfd, dfd, unauth = 0;
159 struct AFSCBFids theFids;
160 struct AFSCBs theCBs;
165 while ((ch=getopt(argc, argv, "ioub:")) != -1) {
169 blksize=atoi(optarg);
186 if (argc - optind < 2) {
187 fprintf(stderr, "Usage: afscp [-i|-o]] [-b xfersz] [-u] source dest\n");
188 fprintf(stderr, " -b Set block size\n");
189 fprintf(stderr, " -i Source is local (copy into AFS)\n");
190 fprintf(stderr, " -o Dest is local (copy out of AFS)\n");
191 fprintf(stderr, " -u Run unauthenticated\n");
195 destpath=argv[optind++];
196 destd=strdup(destpath);
201 if ((destf=strrchr(destd, '/'))) {
209 if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
210 fprintf(stderr, "Cannot get attributes of %s\n", srcf);
213 if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
214 fprintf(stderr, "Cannot get attributes of %s\n", destd);
218 if ((databuffer=malloc(blksize)) == NULL) {
226 if (start_cb_server()) {
227 printf("Cannot start callback service\n");
232 sscindex=scindex_RXKAD;
233 if (unauth || (ssc=get_sc(scell)) == NULL) {
234 ssc=rxnull_NewClientSecurityObject();
235 sscindex=scindex_NULL;
236 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell);*/
238 sscindex=scindex_NULL;
240 if ((sconn=rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
245 printf("Cannot initialize rx connection to source server (%s)\n",
252 if (!slcl && ssrv == dsrv) {
256 if (slcl || strcmp(scell, dcell)){
257 dscindex=scindex_RXKAD;
258 if (unauth || (dsc=get_sc(dcell)) == NULL) {
259 dsc=rxnull_NewClientSecurityObject();
260 dscindex=scindex_NULL;
261 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell);*/
263 dscindex=scindex_NULL;
269 if ((dconn=rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
274 printf("Cannot initialize rx connection to dest server (%s)\n",
282 memset(&sst, 0, sizeof(struct AFSStoreStatus));
285 dfd = open(destpath, O_RDWR|O_CREAT|O_EXCL, 0666);
286 if (dfd < 0 && errno == EEXIST) {
287 printf("%s already exists, overwriting\n", destpath);
288 dfd = open(destpath, O_RDWR|O_TRUNC, 0666);
290 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
291 error_message(errno));
294 } else if (dfd < 0) {
295 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
296 error_message(errno));
300 if ((code=RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst,
301 &dfst, &dcb, &vs))) {
302 if (code == EEXIST) {
303 printf("%s already exits, overwriting\n", destpath);
304 if (statfile(destpath, dcell, &dsrv, &df))
305 fprintf(stderr, "Cannot get attributes of %s\n",
310 printf("Cannot create %s (%s)\n", destpath,
311 error_message(code));
319 sfd = open(srcf, O_RDONLY, 0);
321 fprintf(stderr, "Cannot open %s (%s)\n", srcf,
322 error_message(errno));
325 if (fstat(sfd, &statbuf) < 0) {
326 fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
327 error_message(errno));
332 if ((code=RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
333 printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
334 error_message(code));
342 filesz=statbuf.st_size;
350 if (!slcl) scall=rx_NewCall(sconn);
351 if (!dlcl) dcall=rx_NewCall(dconn);
352 gettimeofday(&start, &tz);
355 if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
356 printf("Unable to fetch data from %s (%s)\n", srcf,
357 error_message(code));
364 sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
365 sst.ClientModTime=statbuf.st_mtime;
366 sst.UnixModeBits=statbuf.st_mode & ~(S_IFMT|S_ISUID|S_ISGID);
368 sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
369 sst.ClientModTime=fst.ClientModTime;
370 sst.UnixModeBits=fst.UnixModeBits & ~(S_IFMT|S_ISUID|S_ISGID);
373 if ((code = StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
374 printf("Unable to store data to %s (%s)\n", destpath,
375 error_message(code));
381 bytesremaining=statbuf.st_size;
383 rx_Read(scall,&bytesremaining,sizeof(afs_int32));
384 bytesremaining=ntohl(bytesremaining);
387 while (bytesremaining >0) {
388 /*printf("%d bytes remaining\n",bytesremaining);*/
390 if ((bytes=read(sfd, databuffer,
391 min(blksize,bytesremaining)))<= 0) {
396 if ((bytes=rx_Read(scall, databuffer,
397 min(blksize,bytesremaining)))<= 0)
401 if (write(dfd, databuffer, bytes) != bytes) {
406 if (rx_Write(dcall, databuffer, bytes) != bytes)
409 bytesremaining -= bytes;
410 /*printf("%d bytes copied\n",bytes);*/
414 if (bytesremaining > 0) {
415 printf("Some network error occured while copying data\n");
419 if (!slcl) fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
420 if (!dlcl) storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
425 if (close(sfd) && !fetchcode) fetchcode = errno;
427 fetchcode = rx_EndCall(scall, fetchcode);
429 if (fetchcode && printcallerrs)
430 printf("Error returned from fetch: %s\n", error_message(fetchcode));
433 if (close(dfd) && !storecode) storecode = errno;
435 storecode = rx_EndCall(dcall, storecode);
437 if (storecode && printcallerrs)
438 printf("Error returned from store: %s\n", error_message(storecode));
440 gettimeofday(&finish, &tz);
443 theFids.AFSCBFids_len=1;
444 theFids.AFSCBFids_val=&sf;
446 theCBs.AFSCBs_val=&scb;
447 scb.CallBackType = CB_DROPPED;
448 if ((code=RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
449 printf("Could not give up source callback: %s\n",
450 error_message(code));
454 theFids.AFSCBFids_len=1;
455 theFids.AFSCBFids_val=&df;
457 theCBs.AFSCBs_val=&dcb;
458 dcb.CallBackType = CB_DROPPED;
459 if ((code=RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
460 printf("Could not give up target callback: %s\n",
461 error_message(code));
470 if (!dlcl && (slcl || dconn != sconn))
471 rx_DestroyConnection(dconn);
473 if (!slcl) rx_DestroyConnection(sconn);
475 if (dsc && dsc != ssc)
477 if (ssc) RXS_Close(ssc);
483 double rate,size,time;
484 if (finish.tv_sec == start.tv_sec) {
485 printf("Copied %d bytes in %d microseconds\n", filesz, finish.tv_usec
488 printf("Copied %d bytes in %d seconds\n", filesz, finish.tv_sec
493 time=finish.tv_sec-start.tv_sec + (finish.tv_usec-start.tv_usec)/1e+06;
495 printf("Transfer rate %g Kbytes/sec\n", rate);