8 #include <sys/socket.h>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
13 #include <sys/select.h>
17 #include <afs/afsint.h>
18 #define FSINT_COMMON_XG 1
19 #include <afs/afscbint.h>
20 #include <sys/ioctl.h>
21 #include <afs/venus.h>
22 #include <afs/cellconfig.h>
23 #include <afs/sys_prototypes.h>
25 #include <afs/afs_consts.h>
27 /*#include <rx/rxkad.h>*/
28 #include <rx/rx_null.h>
29 #include <rx/rx_prototypes.h>
32 #include <afs/com_err.h>
40 statfile(char *path, char *cellname, afs_uint32 * server, struct AFSFid *f)
45 afs_int32 srvbuf[AFS_MAXHOSTS];
48 if (!strncmp(path, "@afs:", 5)) {
55 if (!(p = strtok(NULL, ":"))) {
59 strncpy(cellname, p, MAXCELLCHARS);
61 if (!(p = strtok(NULL, ":"))) {
65 he = gethostbyname(p);
67 printf("Unknown host %s\n", p);
71 memcpy(server, he->h_addr, he->h_length);
73 if (!(p = strtok(NULL, ":"))) {
79 if (!(p = strtok(NULL, ":"))) {
85 if (!(p = strtok(NULL, ":"))) {
91 if (strtok(NULL, ":")) {
92 printf("Too much extra stuff after @afs:...\n");
103 v.out_size = MAXCELLCHARS;
104 if ((code = pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
108 v.out_size = sizeof(struct VenusFid);
109 if ((code = pioctl(path, VIOCGETFID, &v, 1)))
111 memcpy(f, &vf.Fid, sizeof(struct AFSFid));
113 v.out = (char *)srvbuf;
114 v.out_size = sizeof(srvbuf);
115 if ((code = pioctl(path, VIOCWHEREIS, &v, 1)))
117 if (v.out_size <= sizeof(afs_int32))
120 memcpy(server, srvbuf, sizeof(afs_int32));
125 struct rx_securityClass *sc;
128 start_cb_server(void)
130 struct rx_service *s;
132 sc = rxnull_NewServerSecurityObject();
133 s = rx_NewService(0, 1, "afs", &sc, 1, RXAFSCB_ExecuteRequest);
141 /*extern int rx_socket;*/
142 extern unsigned short rx_port;
146 struct sockaddr_in s;
150 fprintf(stderr, "Cannot initialize rx\n");
154 len = sizeof(struct sockaddr_in);
155 if (getsockname(rx_socket, (struct sockaddr *)&s, (socklen_t *)&len)) {
156 perror("getsockname");
159 rx_port = ntohs(s.sin_port);
164 struct rx_securityClass *
165 get_sc(char *cellname)
168 char realm[REALM_SZ];
172 return rxnull_NewClientSecurityObject();
175 ucstring(realm, cellname, REALM_SZ);
177 if (krb_get_cred("afs", "", realm, &c)) {
178 if (get_ad_tkt("afs", "", realm, DEFAULT_TKT_LIFE)) {
181 if (krb_get_cred("afs", "", realm, &c)) {
187 return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno,
188 c.ticket_st.length, c.ticket_st.dat);
192 static volatile int loop_stop = 1;
199 #define scindex_NULL 0
200 #define scindex_RXKAD 2
202 #define scindex scindex_RXKAD
204 main(int argc, char **argv)
206 char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
207 afs_uint32 ssrv, dsrv;
208 char *databuffer, *srcf = NULL, *destd = NULL, *destf = NULL, *destpath = NULL;
211 struct AFSStoreStatus sst;
212 struct AFSFetchStatus fst, dfst;
213 struct AFSVolSync vs;
214 struct AFSCallBack scb, dcb;
215 struct AFSFid sf, dd, df;
218 unsigned long total_xfer = 0;
219 int ch, blksize, bytesremaining, bytes;
220 struct timeval start, finish;
221 struct rx_securityClass *ssc = 0, *dsc = 0;
222 int sscindex, dscindex;
223 struct rx_connection *sconn = NULL, *dconn = NULL;
224 struct rx_call *scall = NULL, *dcall = NULL;
225 struct rx_call *scall_2 = NULL, *dcall_2 = NULL;
226 int code = 0, fetchcode, storecode, printcallerrs = 0;
227 int slcl = 0, dlcl = 0, unlock = 0;
228 int sfd = 0, dfd = 0, unauth = 0;
231 int loop_seconds = 0;
234 struct AFSCBFids theFids;
235 struct AFSCBs theCBs;
240 while ((ch = getopt(argc, argv, "iouUb:s:l:")) != -1) {
243 blksize = atoi(optarg);
252 sleeptime = atoi(optarg);
263 loop_seconds = atoi(optarg);
264 memset(&sa, 0, sizeof(sa));
265 sa.sa_handler = int_handler;
266 sigaction(SIGINT, &sa, NULL);
270 printf("Unknown option '%c'\n", ch);
276 if (argc - optind + unlock < 2) {
278 "Usage: afscp [-i|-o]] [-b xfersz] [-s time] [-l n] [-u] [-U] source [dest]\n");
279 fprintf(stderr, " -b Set block size\n");
280 fprintf(stderr, " -i Source is local (copy into AFS)\n");
281 fprintf(stderr, " -o Dest is local (copy out of AFS)\n");
282 fprintf(stderr, " -s Set the seconds to sleep before reading/writing data\n");
283 fprintf(stderr, " -u Run unauthenticated\n");
284 fprintf(stderr, " -U Send an unlock request for source. (dest path not required)\n");
285 fprintf(stderr, " -l repeat request for N seconds (0 for forever)\n");
286 fprintf(stderr, "source and dest can be paths or specified as:\n");
287 fprintf(stderr, " @afs:cellname:servername:volume:vnode:uniq\n");
290 srcf = argv[optind++];
292 destpath = argv[optind++];
293 destd = strdup(destpath);
298 if ((destf = strrchr(destd, '/'))) {
305 fprintf(stderr, "-i and -U cannot be used together\n");
308 if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
309 fprintf(stderr, "Cannot get attributes of %s\n", srcf);
312 if (!unlock && !dlcl && statfile(destd, dcell, &dsrv, &dd)) {
313 fprintf(stderr, "Cannot get attributes of %s\n", destd);
317 if ((databuffer = malloc(blksize)) == NULL) {
325 if (start_cb_server()) {
326 printf("Cannot start callback service\n");
331 sscindex = scindex_RXKAD;
332 if (unauth || (ssc = get_sc(scell)) == NULL) {
333 ssc = rxnull_NewClientSecurityObject();
334 sscindex = scindex_NULL;
335 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell); */
337 sscindex = scindex_NULL;
340 rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
345 printf("Cannot initialize rx connection to source server (%s)\n",
351 if (!dlcl && !unlock) {
352 if (!slcl && ssrv == dsrv) {
356 if (slcl || strcmp(scell, dcell)) {
357 dscindex = scindex_RXKAD;
358 if (unauth || (dsc = get_sc(dcell)) == NULL) {
359 dsc = rxnull_NewClientSecurityObject();
360 dscindex = scindex_NULL;
361 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell); */
363 dscindex = scindex_NULL;
370 rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
376 ("Cannot initialize rx connection to dest server (%s)\n",
387 } else if (first == 1) {
391 memset(&sst, 0, sizeof(struct AFSStoreStatus));
393 if (dlcl && !unlock) {
394 dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666);
395 if (dfd < 0 && errno == EEXIST) {
397 printf("%s already exists, overwriting\n", destpath);
399 dfd = open(destpath, O_RDWR | O_TRUNC, 0666);
401 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
402 afs_error_message(errno));
405 } else if (dfd < 0) {
406 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
407 afs_error_message(errno));
410 } else if (!unlock) {
412 RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb,
414 if (code == EEXIST) {
416 printf("%s already exits, overwriting\n", destpath);
418 if (statfile(destpath, dcell, &dsrv, &df))
419 fprintf(stderr, "Cannot get attributes of %s\n",
424 printf("Cannot create %s (%s)\n", destpath,
425 afs_error_message(code));
433 sfd = open(srcf, O_RDONLY, 0);
435 fprintf(stderr, "Cannot open %s (%s)\n", srcf,
436 afs_error_message(errno));
439 if (fstat(sfd, &statbuf) < 0) {
440 fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
441 afs_error_message(errno));
446 if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
447 printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
448 afs_error_message(code));
456 filesz = statbuf.st_size;
460 total_xfer += filesz;
465 if (!slcl && !unlock) {
467 scall = rx_NewCall(sconn);
471 scall_2 = rx_NewCall(sconn);
473 if (!dlcl && !unlock) {
475 dcall = rx_NewCall(dconn);
479 dcall_2 = rx_NewCall(dconn);
482 gettimeofday(&start, NULL);
487 printf("Sending 1 unlock for %s (%d locks)\n", srcf, fst.lockCount);
488 if ((code = RXAFS_ReleaseLock(sconn, &sf, &vs))) {
489 printf("Unable to unlock %s (%s)\n", srcf,
490 afs_error_message(code));
493 printf("No locks for %s\n", srcf);
500 if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
501 printf("Unable to fetch data from %s (%s)\n", srcf,
502 afs_error_message(code));
509 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
510 sst.ClientModTime = statbuf.st_mtime;
512 statbuf.st_mode & ~(S_IFMT | S_ISUID | S_ISGID);
514 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
515 sst.ClientModTime = fst.ClientModTime;
517 fst.UnixModeBits & ~(S_IFMT | S_ISUID | S_ISGID);
521 StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
522 printf("Unable to store data to %s (%s)\n", destpath,
523 afs_error_message(code));
529 bytesremaining = statbuf.st_size;
531 rx_Read(scall, (char *)&bytesremaining, sizeof(afs_int32));
532 bytesremaining = ntohl(bytesremaining);
535 while (bytesremaining > 0) {
536 /*printf("%d bytes remaining\n",bytesremaining); */
539 read(sfd, databuffer, min(blksize, bytesremaining))) <= 0) {
545 rx_Read(scall, databuffer,
546 min(blksize, bytesremaining))) <= 0)
550 if (write(dfd, databuffer, bytes) != bytes) {
555 if (rx_Write(dcall, databuffer, bytes) != bytes)
560 #ifdef AFS_PTHREAD_ENV
563 IOMGR_Sleep(sleeptime);
565 /* only sleep once */
569 bytesremaining -= bytes;
570 /*printf("%d bytes copied\n",bytes); */
574 if (bytesremaining > 0) {
575 printf("Some network error occured while copying data\n");
580 fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
582 storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
587 if (close(sfd) && !fetchcode)
590 fetchcode = rx_EndCall(scall, fetchcode);
593 printf("Error returned from fetch: %s\n", afs_error_message(fetchcode));
596 if (close(dfd) && !storecode)
598 } else if (!unlock) {
599 storecode = rx_EndCall(dcall, storecode);
602 printf("Error returned from store: %s\n", afs_error_message(storecode));
607 if (loop_seconds == 0) {
610 gettimeofday(&cur, NULL);
611 elapsed = cur.tv_sec - start.tv_sec + (cur.tv_usec - start.tv_usec) / 1e+06;
612 if (elapsed < loop_seconds) {
617 gettimeofday(&finish, NULL);
620 theFids.AFSCBFids_len = 1;
621 theFids.AFSCBFids_val = &sf;
622 theCBs.AFSCBs_len = 1;
623 theCBs.AFSCBs_val = &scb;
624 scb.CallBackType = CB_DROPPED;
625 if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
626 printf("Could not give up source callback: %s\n",
627 afs_error_message(code));
631 theFids.AFSCBFids_len = 1;
632 theFids.AFSCBFids_val = &df;
633 theCBs.AFSCBs_len = 1;
634 theCBs.AFSCBs_val = &dcb;
635 dcb.CallBackType = CB_DROPPED;
636 if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
637 printf("Could not give up target callback: %s\n",
638 afs_error_message(code));
647 if (!dlcl && !unlock && (slcl || dconn != sconn))
648 rx_DestroyConnection(dconn);
651 rx_DestroyConnection(sconn);
653 if (dsc && dsc != ssc)
661 if (printcallerrs && !unlock) {
662 double rate, size, time;
663 if (finish.tv_sec == start.tv_sec) {
664 printf("Copied %lu bytes in %d microseconds\n", total_xfer,
665 (int)(finish.tv_usec - start.tv_usec));
667 printf("Copied %lu bytes in %d seconds\n", total_xfer,
668 (int)(finish.tv_sec - start.tv_sec));
671 size = total_xfer / 1024.0;
673 finish.tv_sec - start.tv_sec + (finish.tv_usec -
674 start.tv_usec) / 1e+06;
676 printf("Transfer rate %.4g Kbytes/sec\n", rate);