5 #include <sys/socket.h>
6 #include <netinet/in.h>
10 #include <sys/select.h>
14 #include <afs/param.h>
15 #include <afs/afsint.h>
16 #define FSINT_COMMON_XG 1
17 #include <afs/afscbint.h>
18 #include <sys/ioctl.h>
19 #include <afs/venus.h>
20 #include <afs/cellconfig.h>
21 #include <afs/sys_prototypes.h>
23 #include <afs/afs_consts.h>
25 /*#include <rx/rxkad.h>*/
26 #include <rx/rx_null.h>
27 #include <rx/rx_prototypes.h>
30 #include <afs/com_err.h>
38 statfile(char *path, char *cellname, afs_uint32 * server, struct AFSFid *f)
43 afs_int32 srvbuf[AFS_MAXHOSTS];
46 if (!strncmp(path, "@afs:", 5)) {
53 if (!(p = strtok(NULL, ":"))) {
57 strncpy(cellname, p, MAXCELLCHARS);
59 if (!(p = strtok(NULL, ":"))) {
63 he = gethostbyname(p);
65 printf("Unknown host %s\n", p);
69 memcpy(server, he->h_addr, he->h_length);
71 if (!(p = strtok(NULL, ":"))) {
77 if (!(p = strtok(NULL, ":"))) {
83 if (!(p = strtok(NULL, ":"))) {
89 if (strtok(NULL, ":")) {
90 printf("Too much extra stuff after @afs:...\n");
101 v.out_size = MAXCELLCHARS;
102 if ((code = pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
106 v.out_size = sizeof(struct VenusFid);
107 if ((code = pioctl(path, VIOCGETFID, &v, 1)))
109 memcpy(f, &vf.Fid, sizeof(struct AFSFid));
111 v.out = (char *)srvbuf;
112 v.out_size = sizeof(srvbuf);
113 if ((code = pioctl(path, VIOCWHEREIS, &v, 1)))
115 if (v.out_size <= sizeof(afs_int32))
118 memcpy(server, srvbuf, sizeof(afs_int32));
123 struct rx_securityClass *sc;
126 start_cb_server(void)
128 struct rx_service *s;
130 sc = rxnull_NewServerSecurityObject();
131 s = rx_NewService(0, 1, "afs", &sc, 1, RXAFSCB_ExecuteRequest);
139 /*extern int rx_socket;*/
140 extern unsigned short rx_port;
144 struct sockaddr_in s;
148 fprintf(stderr, "Cannot initialize rx\n");
152 len = sizeof(struct sockaddr_in);
153 if (getsockname(rx_socket, (struct sockaddr *)&s, (socklen_t *)&len)) {
154 perror("getsockname");
157 rx_port = ntohs(s.sin_port);
162 struct rx_securityClass *
163 get_sc(char *cellname)
166 char realm[REALM_SZ];
170 return rxnull_NewClientSecurityObject();
173 ucstring(realm, cellname, REALM_SZ);
175 if (krb_get_cred("afs", "", realm, &c)) {
176 if (get_ad_tkt("afs", "", realm, DEFAULT_TKT_LIFE)) {
179 if (krb_get_cred("afs", "", realm, &c)) {
185 return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno,
186 c.ticket_st.length, c.ticket_st.dat);
190 #define scindex_NULL 0
191 #define scindex_RXKAD 2
193 #define scindex scindex_RXKAD
195 main(int argc, char **argv)
197 char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
198 afs_uint32 ssrv, dsrv;
199 char *databuffer, *srcf = NULL, *destd = NULL, *destf = NULL, *destpath = NULL;
202 struct AFSStoreStatus sst;
203 struct AFSFetchStatus fst, dfst;
204 struct AFSVolSync vs;
205 struct AFSCallBack scb, dcb;
206 struct AFSFid sf, dd, df;
209 int ch, blksize, bytesremaining, bytes;
210 struct timeval start, finish;
212 struct rx_securityClass *ssc = 0, *dsc = 0;
213 int sscindex, dscindex;
214 struct rx_connection *sconn = NULL, *dconn = NULL;
215 struct rx_call *scall = NULL, *dcall = NULL;
216 int code = 0, fetchcode, storecode, printcallerrs = 0;
217 int slcl = 0, dlcl = 0, unlock = 0;
218 int sfd = 0, dfd = 0, unauth = 0;
220 struct AFSCBFids theFids;
221 struct AFSCBs theCBs;
226 while ((ch = getopt(argc, argv, "iouUb:")) != -1) {
229 blksize = atoi(optarg);
244 printf("Unknown option '%c'\n", ch);
250 if (argc - optind + unlock < 2) {
252 "Usage: afscp [-i|-o]] [-b xfersz] [-u] [-U] source [dest]\n");
253 fprintf(stderr, " -b Set block size\n");
254 fprintf(stderr, " -i Source is local (copy into AFS)\n");
255 fprintf(stderr, " -o Dest is local (copy out of AFS)\n");
256 fprintf(stderr, " -u Run unauthenticated\n");
257 fprintf(stderr, " -U Send an unlock request for source. (dest path not required)\n");
258 fprintf(stderr, "source and dest can be paths or specified as:\n");
259 fprintf(stderr, " @afs:cellname:servername:volume:vnode:uniq\n");
262 srcf = argv[optind++];
264 destpath = argv[optind++];
265 destd = strdup(destpath);
270 if ((destf = strrchr(destd, '/'))) {
277 fprintf(stderr, "-i and -U cannot be used together\n");
280 if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
281 fprintf(stderr, "Cannot get attributes of %s\n", srcf);
284 if (!unlock && !dlcl && statfile(destd, dcell, &dsrv, &dd)) {
285 fprintf(stderr, "Cannot get attributes of %s\n", destd);
289 if ((databuffer = malloc(blksize)) == NULL) {
297 if (start_cb_server()) {
298 printf("Cannot start callback service\n");
303 sscindex = scindex_RXKAD;
304 if (unauth || (ssc = get_sc(scell)) == NULL) {
305 ssc = rxnull_NewClientSecurityObject();
306 sscindex = scindex_NULL;
307 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell); */
309 sscindex = scindex_NULL;
312 rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
317 printf("Cannot initialize rx connection to source server (%s)\n",
323 if (!dlcl && !unlock) {
324 if (!slcl && ssrv == dsrv) {
328 if (slcl || strcmp(scell, dcell)) {
329 dscindex = scindex_RXKAD;
330 if (unauth || (dsc = get_sc(dcell)) == NULL) {
331 dsc = rxnull_NewClientSecurityObject();
332 dscindex = scindex_NULL;
333 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell); */
335 dscindex = scindex_NULL;
342 rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
348 ("Cannot initialize rx connection to dest server (%s)\n",
356 memset(&sst, 0, sizeof(struct AFSStoreStatus));
358 if (dlcl && !unlock) {
359 dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666);
360 if (dfd < 0 && errno == EEXIST) {
361 printf("%s already exists, overwriting\n", destpath);
362 dfd = open(destpath, O_RDWR | O_TRUNC, 0666);
364 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
365 afs_error_message(errno));
368 } else if (dfd < 0) {
369 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
370 afs_error_message(errno));
373 } else if (!unlock) {
375 RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb,
377 if (code == EEXIST) {
378 printf("%s already exits, overwriting\n", destpath);
379 if (statfile(destpath, dcell, &dsrv, &df))
380 fprintf(stderr, "Cannot get attributes of %s\n",
385 printf("Cannot create %s (%s)\n", destpath,
386 afs_error_message(code));
394 sfd = open(srcf, O_RDONLY, 0);
396 fprintf(stderr, "Cannot open %s (%s)\n", srcf,
397 afs_error_message(errno));
400 if (fstat(sfd, &statbuf) < 0) {
401 fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
402 afs_error_message(errno));
407 if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
408 printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
409 afs_error_message(code));
417 filesz = statbuf.st_size;
425 if (!slcl && !unlock)
426 scall = rx_NewCall(sconn);
427 if (!dlcl && !unlock)
428 dcall = rx_NewCall(dconn);
429 gettimeofday(&start, &tz);
432 printf("Sending 1 unlock for %s (%d locks)\n", srcf, fst.lockCount);
433 if ((code = RXAFS_ReleaseLock(sconn, &sf, &vs))) {
434 printf("Unable to unlock %s (%s)\n", srcf,
435 afs_error_message(code));
438 printf("No locks for %s\n", srcf);
445 if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
446 printf("Unable to fetch data from %s (%s)\n", srcf,
447 afs_error_message(code));
454 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
455 sst.ClientModTime = statbuf.st_mtime;
457 statbuf.st_mode & ~(S_IFMT | S_ISUID | S_ISGID);
459 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
460 sst.ClientModTime = fst.ClientModTime;
462 fst.UnixModeBits & ~(S_IFMT | S_ISUID | S_ISGID);
466 StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
467 printf("Unable to store data to %s (%s)\n", destpath,
468 afs_error_message(code));
474 bytesremaining = statbuf.st_size;
476 rx_Read(scall, (char *)&bytesremaining, sizeof(afs_int32));
477 bytesremaining = ntohl(bytesremaining);
480 while (bytesremaining > 0) {
481 /*printf("%d bytes remaining\n",bytesremaining); */
484 read(sfd, databuffer, min(blksize, bytesremaining))) <= 0) {
490 rx_Read(scall, databuffer,
491 min(blksize, bytesremaining))) <= 0)
495 if (write(dfd, databuffer, bytes) != bytes) {
500 if (rx_Write(dcall, databuffer, bytes) != bytes)
503 bytesremaining -= bytes;
504 /*printf("%d bytes copied\n",bytes); */
508 if (bytesremaining > 0) {
509 printf("Some network error occured while copying data\n");
514 fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
516 storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
521 if (close(sfd) && !fetchcode)
524 fetchcode = rx_EndCall(scall, fetchcode);
526 if (fetchcode && printcallerrs)
527 printf("Error returned from fetch: %s\n", afs_error_message(fetchcode));
530 if (close(dfd) && !storecode)
532 } else if (!unlock) {
533 storecode = rx_EndCall(dcall, storecode);
535 if (storecode && printcallerrs)
536 printf("Error returned from store: %s\n", afs_error_message(storecode));
538 gettimeofday(&finish, &tz);
541 theFids.AFSCBFids_len = 1;
542 theFids.AFSCBFids_val = &sf;
543 theCBs.AFSCBs_len = 1;
544 theCBs.AFSCBs_val = &scb;
545 scb.CallBackType = CB_DROPPED;
546 if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
547 printf("Could not give up source callback: %s\n",
548 afs_error_message(code));
552 theFids.AFSCBFids_len = 1;
553 theFids.AFSCBFids_val = &df;
554 theCBs.AFSCBs_len = 1;
555 theCBs.AFSCBs_val = &dcb;
556 dcb.CallBackType = CB_DROPPED;
557 if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
558 printf("Could not give up target callback: %s\n",
559 afs_error_message(code));
568 if (!dlcl && !unlock && (slcl || dconn != sconn))
569 rx_DestroyConnection(dconn);
572 rx_DestroyConnection(sconn);
574 if (dsc && dsc != ssc)
582 if (printcallerrs && !unlock) {
583 double rate, size, time;
584 if (finish.tv_sec == start.tv_sec) {
585 printf("Copied %d bytes in %d microseconds\n", filesz,
586 finish.tv_usec - start.tv_usec);
588 printf("Copied %d bytes in %d seconds\n", filesz,
589 (int)(finish.tv_sec - start.tv_sec));
592 size = filesz / 1024.0;
594 finish.tv_sec - start.tv_sec + (finish.tv_usec -
595 start.tv_usec) / 1e+06;
597 printf("Transfer rate %g Kbytes/sec\n", rate);