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 #include <sys/ioctl.h>
17 #include <afs/venus.h>
18 #include <afs/cellconfig.h>
21 /*#include <rx/rxkad.h>*/
22 #include <rx/rx_null.h>
25 #include <afs/com_err.h>
33 statfile(char *path, char *cellname, afs_uint32 * server, struct AFSFid *f)
38 afs_int32 srvbuf[MAXHOSTS];
41 if (!strncmp(path, "@afs:", 5)) {
42 char *pdup, *p, *host, *id;
48 if (!(p = strtok(NULL, ":"))) {
52 strncpy(cellname, p, MAXCELLCHARS);
54 if (!(p = strtok(NULL, ":"))) {
58 he = gethostbyname(p);
60 printf("Unknown host %s\n", p);
64 memcpy(server, he->h_addr, he->h_length);
66 if (!(p = strtok(NULL, ":"))) {
72 if (!(p = strtok(NULL, ":"))) {
78 if (!(p = strtok(NULL, ":"))) {
84 if (strtok(NULL, ":")) {
85 printf("Too much extra stuff after @afs:...\n");
96 v.out_size = MAXCELLCHARS;
97 if ((code = pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
101 v.out_size = sizeof(struct VenusFid);
102 if ((code = pioctl(path, VIOCGETFID, &v, 1)))
104 memcpy(f, &vf.Fid, sizeof(struct AFSFid));
106 v.out = (char *)srvbuf;
107 v.out_size = sizeof(srvbuf);
108 if ((code = pioctl(path, VIOCWHEREIS, &v, 1)))
110 if (v.out_size <= sizeof(afs_int32))
113 memcpy(server, srvbuf, sizeof(afs_int32));
118 extern int RXAFSCB_ExecuteRequest();
119 struct rx_securityClass *sc;
124 struct rx_service *s;
126 sc = rxnull_NewServerSecurityObject();
127 s = rx_NewService(0, 1, "afs", &sc, 1, RXAFSCB_ExecuteRequest);
135 /*extern int rx_socket;*/
136 extern unsigned short rx_port;
140 struct sockaddr_in s;
144 fprintf(stderr, "Cannot initialize rx\n");
148 len = sizeof(struct sockaddr_in);
149 if (getsockname(rx_socket, &s, &len)) {
150 perror("getsockname");
153 rx_port = ntohs(s.sin_port);
158 struct rx_securityClass *
159 get_sc(char *cellname)
162 char realm[REALM_SZ];
166 return rxnull_NewClientSecurityObject();
169 ucstring(realm, cellname, REALM_SZ);
171 if (krb_get_cred("afs", "", realm, &c)) {
172 if (get_ad_tkt("afs", "", realm, DEFAULT_TKT_LIFE)) {
175 if (krb_get_cred("afs", "", realm, &c)) {
181 return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno,
182 c.ticket_st.length, c.ticket_st.dat);
186 #define scindex_NULL 0
187 #define scindex_RXKAD 2
189 #define scindex scindex_RXKAD
191 main(int argc, char **argv)
193 char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
194 afs_uint32 ssrv, dsrv;
195 char *databuffer, *srcf, *destd, *destf, *destpath;
198 struct AFSStoreStatus sst;
199 struct AFSFetchStatus fst, dfst;
200 struct AFSVolSync vs;
201 struct AFSCallBack scb, dcb;
202 struct AFSFid sf, dd, df;
205 int ch, blksize, bytesremaining, bytes;
206 struct timeval start, finish;
208 struct rx_securityClass *ssc = 0, *dsc = 0;
209 int sscindex, dscindex;
210 struct rx_connection *sconn, *dconn;
211 struct rx_call *scall, *dcall;
212 int code, fetchcode, storecode, printcallerrs;
213 int slcl = 0, dlcl = 0;
214 int sfd, dfd, unauth = 0;
216 struct AFSCBFids theFids;
217 struct AFSCBs theCBs;
222 while ((ch = getopt(argc, argv, "ioub:")) != -1) {
225 blksize = atoi(optarg);
237 printf("Unknown option '%c'\n", ch);
243 if (argc - optind < 2) {
245 "Usage: afscp [-i|-o]] [-b xfersz] [-u] source dest\n");
246 fprintf(stderr, " -b Set block size\n");
247 fprintf(stderr, " -i Source is local (copy into AFS)\n");
248 fprintf(stderr, " -o Dest is local (copy out of AFS)\n");
249 fprintf(stderr, " -u Run unauthenticated\n");
250 fprintf(stderr, "source and dest can be paths or specified as:\n");
251 fprintf(stderr, " @afs:cellname:servername:volume:vnode:uniq\n");
254 srcf = argv[optind++];
255 destpath = argv[optind++];
256 destd = strdup(destpath);
261 if ((destf = strrchr(destd, '/'))) {
269 if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
270 fprintf(stderr, "Cannot get attributes of %s\n", srcf);
273 if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
274 fprintf(stderr, "Cannot get attributes of %s\n", destd);
278 if ((databuffer = malloc(blksize)) == NULL) {
286 if (start_cb_server()) {
287 printf("Cannot start callback service\n");
292 sscindex = scindex_RXKAD;
293 if (unauth || (ssc = get_sc(scell)) == NULL) {
294 ssc = rxnull_NewClientSecurityObject();
295 sscindex = scindex_NULL;
296 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell); */
298 sscindex = scindex_NULL;
301 rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
306 printf("Cannot initialize rx connection to source server (%s)\n",
313 if (!slcl && ssrv == dsrv) {
317 if (slcl || strcmp(scell, dcell)) {
318 dscindex = scindex_RXKAD;
319 if (unauth || (dsc = get_sc(dcell)) == NULL) {
320 dsc = rxnull_NewClientSecurityObject();
321 dscindex = scindex_NULL;
322 /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell); */
324 dscindex = scindex_NULL;
331 rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
337 ("Cannot initialize rx connection to dest server (%s)\n",
345 memset(&sst, 0, sizeof(struct AFSStoreStatus));
348 dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666);
349 if (dfd < 0 && errno == EEXIST) {
350 printf("%s already exists, overwriting\n", destpath);
351 dfd = open(destpath, O_RDWR | O_TRUNC, 0666);
353 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
354 error_message(errno));
357 } else if (dfd < 0) {
358 fprintf(stderr, "Cannot open %s (%s)\n", destpath,
359 error_message(errno));
364 RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb,
366 if (code == EEXIST) {
367 printf("%s already exits, overwriting\n", destpath);
368 if (statfile(destpath, dcell, &dsrv, &df))
369 fprintf(stderr, "Cannot get attributes of %s\n",
374 printf("Cannot create %s (%s)\n", destpath,
375 error_message(code));
383 sfd = open(srcf, O_RDONLY, 0);
385 fprintf(stderr, "Cannot open %s (%s)\n", srcf,
386 error_message(errno));
389 if (fstat(sfd, &statbuf) < 0) {
390 fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
391 error_message(errno));
396 if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
397 printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
398 error_message(code));
406 filesz = statbuf.st_size;
415 scall = rx_NewCall(sconn);
417 dcall = rx_NewCall(dconn);
418 gettimeofday(&start, &tz);
421 if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
422 printf("Unable to fetch data from %s (%s)\n", srcf,
423 error_message(code));
430 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
431 sst.ClientModTime = statbuf.st_mtime;
433 statbuf.st_mode & ~(S_IFMT | S_ISUID | S_ISGID);
435 sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
436 sst.ClientModTime = fst.ClientModTime;
438 fst.UnixModeBits & ~(S_IFMT | S_ISUID | S_ISGID);
442 StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
443 printf("Unable to store data to %s (%s)\n", destpath,
444 error_message(code));
450 bytesremaining = statbuf.st_size;
452 rx_Read(scall, &bytesremaining, sizeof(afs_int32));
453 bytesremaining = ntohl(bytesremaining);
456 while (bytesremaining > 0) {
457 /*printf("%d bytes remaining\n",bytesremaining); */
460 read(sfd, databuffer, min(blksize, bytesremaining))) <= 0) {
466 rx_Read(scall, databuffer,
467 min(blksize, bytesremaining))) <= 0)
471 if (write(dfd, databuffer, bytes) != bytes) {
476 if (rx_Write(dcall, databuffer, bytes) != bytes)
479 bytesremaining -= bytes;
480 /*printf("%d bytes copied\n",bytes); */
484 if (bytesremaining > 0) {
485 printf("Some network error occured while copying data\n");
490 fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
492 storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
497 if (close(sfd) && !fetchcode)
500 fetchcode = rx_EndCall(scall, fetchcode);
502 if (fetchcode && printcallerrs)
503 printf("Error returned from fetch: %s\n", error_message(fetchcode));
506 if (close(dfd) && !storecode)
509 storecode = rx_EndCall(dcall, storecode);
511 if (storecode && printcallerrs)
512 printf("Error returned from store: %s\n", error_message(storecode));
514 gettimeofday(&finish, &tz);
517 theFids.AFSCBFids_len = 1;
518 theFids.AFSCBFids_val = &sf;
519 theCBs.AFSCBs_len = 1;
520 theCBs.AFSCBs_val = &scb;
521 scb.CallBackType = CB_DROPPED;
522 if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
523 printf("Could not give up source callback: %s\n",
524 error_message(code));
528 theFids.AFSCBFids_len = 1;
529 theFids.AFSCBFids_val = &df;
530 theCBs.AFSCBs_len = 1;
531 theCBs.AFSCBs_val = &dcb;
532 dcb.CallBackType = CB_DROPPED;
533 if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
534 printf("Could not give up target callback: %s\n",
535 error_message(code));
544 if (!dlcl && (slcl || dconn != sconn))
545 rx_DestroyConnection(dconn);
548 rx_DestroyConnection(sconn);
550 if (dsc && dsc != ssc)
559 double rate, size, time;
560 if (finish.tv_sec == start.tv_sec) {
561 printf("Copied %d bytes in %d microseconds\n", filesz,
562 finish.tv_usec - start.tv_usec);
564 printf("Copied %d bytes in %d seconds\n", filesz,
565 finish.tv_sec - start.tv_sec);
568 size = filesz / 1024.0;
570 finish.tv_sec - start.tv_sec + (finish.tv_usec -
571 start.tv_usec) / 1e+06;
573 printf("Transfer rate %g Kbytes/sec\n", rate);