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>
24 #include <afs/com_err.h>
32 statfile(char *path, char *cellname, afs_uint32 * server, struct AFSFid *f)
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));
53 v.out = (char *)srvbuf;
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;
73 sc = rxnull_NewServerSecurityObject();
74 s = rx_NewService(0, 1, "afs", &sc, 1, RXAFSCB_ExecuteRequest);
82 /*extern int rx_socket;*/
83 extern unsigned short rx_port;
91 fprintf(stderr, "Cannot initialize rx\n");
95 len = sizeof(struct sockaddr_in);
96 if (getsockname(rx_socket, &s, &len)) {
97 perror("getsockname");
100 rx_port = ntohs(s.sin_port);
105 struct rx_securityClass *
106 get_sc(char *cellname)
109 char realm[REALM_SZ];
113 return rxnull_NewClientSecurityObject();
116 ucstring(realm, cellname, REALM_SZ);
118 if (krb_get_cred("afs", "", realm, &c)) {
119 if (get_ad_tkt("afs", "", realm, DEFAULT_TKT_LIFE)) {
122 if (krb_get_cred("afs", "", realm, &c)) {
128 return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno,
129 c.ticket_st.length, c.ticket_st.dat);
133 #define scindex_NULL 0
134 #define scindex_RXKAD 2
136 #define scindex scindex_RXKAD
138 main(int argc, char **argv)
140 char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
141 afs_uint32 ssrv, dsrv;
142 char *databuffer, *srcf, *destd, *destf, *destpath;
145 struct AFSStoreStatus sst;
146 struct AFSFetchStatus fst, dfst;
147 struct AFSVolSync vs;
148 struct AFSCallBack scb, dcb;
149 struct AFSFid sf, dd, df;
152 int ch, blksize, bytesremaining, bytes;
153 struct timeval start, finish;
155 struct rx_securityClass *ssc = 0, *dsc = 0;
156 int sscindex, dscindex;
157 struct rx_connection *sconn, *dconn;
158 struct rx_call *scall, *dcall;
159 int code, fetchcode, storecode, printcallerrs;
160 int slcl = 0, dlcl = 0;
161 int sfd, dfd, unauth = 0;
163 struct AFSCBFids theFids;
164 struct AFSCBs theCBs;
169 while ((ch = getopt(argc, argv, "ioub:")) != -1) {
172 blksize = atoi(optarg);
189 if (argc - optind < 2) {
191 "Usage: afscp [-i|-o]] [-b xfersz] [-u] source dest\n");
192 fprintf(stderr, " -b Set block size\n");
193 fprintf(stderr, " -i Source is local (copy into AFS)\n");
194 fprintf(stderr, " -o Dest is local (copy out of AFS)\n");
195 fprintf(stderr, " -u Run unauthenticated\n");
198 srcf = argv[optind++];
199 destpath = argv[optind++];
200 destd = strdup(destpath);
205 if ((destf = strrchr(destd, '/'))) {
213 if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
214 fprintf(stderr, "Cannot get attributes of %s\n", srcf);
217 if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
218 fprintf(stderr, "Cannot get attributes of %s\n", destd);
222 if ((databuffer = malloc(blksize)) == NULL) {
230 if (start_cb_server()) {
231 printf("Cannot start callback service\n");
236 sscindex = scindex_RXKAD;
237 if (unauth || (ssc = get_sc(scell)) == NULL) {
238 ssc = rxnull_NewClientSecurityObject();
239 sscindex = scindex_NULL;
240 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell); */
242 sscindex = scindex_NULL;
245 rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
250 printf("Cannot initialize rx connection to source server (%s)\n",
257 if (!slcl && ssrv == dsrv) {
261 if (slcl || strcmp(scell, dcell)) {
262 dscindex = scindex_RXKAD;
263 if (unauth || (dsc = get_sc(dcell)) == NULL) {
264 dsc = rxnull_NewClientSecurityObject();
265 dscindex = scindex_NULL;
266 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell); */
268 dscindex = scindex_NULL;
275 rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
281 ("Cannot initialize rx connection to dest server (%s)\n",
289 memset(&sst, 0, sizeof(struct AFSStoreStatus));
292 dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666);
293 if (dfd < 0 && errno == EEXIST) {
294 printf("%s already exists, overwriting\n", destpath);
295 dfd = open(destpath, O_RDWR | O_TRUNC, 0666);
297 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
298 error_message(errno));
301 } else if (dfd < 0) {
302 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
303 error_message(errno));
308 RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb,
310 if (code == EEXIST) {
311 printf("%s already exits, overwriting\n", destpath);
312 if (statfile(destpath, dcell, &dsrv, &df))
313 fprintf(stderr, "Cannot get attributes of %s\n",
318 printf("Cannot create %s (%s)\n", destpath,
319 error_message(code));
327 sfd = open(srcf, O_RDONLY, 0);
329 fprintf(stderr, "Cannot open %s (%s)\n", srcf,
330 error_message(errno));
333 if (fstat(sfd, &statbuf) < 0) {
334 fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
335 error_message(errno));
340 if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
341 printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
342 error_message(code));
350 filesz = statbuf.st_size;
359 scall = rx_NewCall(sconn);
361 dcall = rx_NewCall(dconn);
362 gettimeofday(&start, &tz);
365 if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
366 printf("Unable to fetch data from %s (%s)\n", srcf,
367 error_message(code));
374 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
375 sst.ClientModTime = statbuf.st_mtime;
377 statbuf.st_mode & ~(S_IFMT | S_ISUID | S_ISGID);
379 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
380 sst.ClientModTime = fst.ClientModTime;
382 fst.UnixModeBits & ~(S_IFMT | S_ISUID | S_ISGID);
386 StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
387 printf("Unable to store data to %s (%s)\n", destpath,
388 error_message(code));
394 bytesremaining = statbuf.st_size;
396 rx_Read(scall, &bytesremaining, sizeof(afs_int32));
397 bytesremaining = ntohl(bytesremaining);
400 while (bytesremaining > 0) {
401 /*printf("%d bytes remaining\n",bytesremaining); */
404 read(sfd, databuffer, min(blksize, bytesremaining))) <= 0) {
410 rx_Read(scall, databuffer,
411 min(blksize, bytesremaining))) <= 0)
415 if (write(dfd, databuffer, bytes) != bytes) {
420 if (rx_Write(dcall, databuffer, bytes) != bytes)
423 bytesremaining -= bytes;
424 /*printf("%d bytes copied\n",bytes); */
428 if (bytesremaining > 0) {
429 printf("Some network error occured while copying data\n");
434 fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
436 storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
441 if (close(sfd) && !fetchcode)
444 fetchcode = rx_EndCall(scall, fetchcode);
446 if (fetchcode && printcallerrs)
447 printf("Error returned from fetch: %s\n", error_message(fetchcode));
450 if (close(dfd) && !storecode)
453 storecode = rx_EndCall(dcall, storecode);
455 if (storecode && printcallerrs)
456 printf("Error returned from store: %s\n", error_message(storecode));
458 gettimeofday(&finish, &tz);
461 theFids.AFSCBFids_len = 1;
462 theFids.AFSCBFids_val = &sf;
463 theCBs.AFSCBs_len = 1;
464 theCBs.AFSCBs_val = &scb;
465 scb.CallBackType = CB_DROPPED;
466 if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
467 printf("Could not give up source callback: %s\n",
468 error_message(code));
472 theFids.AFSCBFids_len = 1;
473 theFids.AFSCBFids_val = &df;
474 theCBs.AFSCBs_len = 1;
475 theCBs.AFSCBs_val = &dcb;
476 dcb.CallBackType = CB_DROPPED;
477 if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
478 printf("Could not give up target callback: %s\n",
479 error_message(code));
488 if (!dlcl && (slcl || dconn != sconn))
489 rx_DestroyConnection(dconn);
492 rx_DestroyConnection(sconn);
494 if (dsc && dsc != ssc)
503 double rate, size, time;
504 if (finish.tv_sec == start.tv_sec) {
505 printf("Copied %d bytes in %d microseconds\n", filesz,
506 finish.tv_usec - start.tv_usec);
508 printf("Copied %d bytes in %d seconds\n", filesz,
509 finish.tv_sec - start.tv_sec);
512 size = filesz / 1024.0;
514 finish.tv_sec - start.tv_sec + (finish.tv_usec -
515 start.tv_usec) / 1e+06;
517 printf("Transfer rate %g Kbytes/sec\n", rate);