functionality-test-suite-20020114
[openafs.git] / src / tests / afscp.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #include <arpa/inet.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <sys/select.h>
11 #include <sys/stat.h>
12
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>
18 #include <afs/afs.h>
19
20 /*#include <rx/rxkad.h>*/
21 #include <rx/rx_null.h>
22
23 /*#include <krb.h>*/
24 #include <com_err.h>
25
26 struct VenusFid {
27     afs_int32 Cell;
28     struct AFSFid Fid;
29 };
30
31 int statfile(char *path, char *cellname, afs_uint32 *server, 
32              struct AFSFid *f)
33 {
34      
35      struct ViceIoctl v;
36      struct VenusFid vf;
37      afs_int32 srvbuf[MAXHOSTS];
38      int code;
39      
40      v.in=0;
41      v.in_size=0;
42      v.out=cellname;
43      v.out_size=MAXCELLCHARS;
44      if ((code=pioctl(path, VIOC_FILE_CELL_NAME, &v, 1)))
45           return code;
46      
47      v.out=(char *)&vf;
48      v.out_size=sizeof(struct VenusFid);
49      if ((code=pioctl(path, VIOCGETFID, &v, 1)))
50           return code;
51      memcpy(f,&vf.Fid, sizeof(struct AFSFid));
52      
53      v.out=(char *)srvbuf;
54      v.out_size=sizeof(srvbuf);
55      if ((code=pioctl(path, VIOCWHEREIS, &v, 1)))
56           return code;
57      if (v.out_size <= sizeof(afs_int32))
58           return EINVAL;
59      
60      memcpy(server, srvbuf, sizeof(afs_int32));
61      return 0;
62 }
63
64
65 extern int RXAFSCB_ExecuteRequest();
66 struct rx_securityClass *sc;
67
68 extern int start_cb_server() 
69 {
70      struct rx_service *s;
71
72      sc=rxnull_NewServerSecurityObject();
73      s=rx_NewService(0,1,"afs", &sc, 1, RXAFSCB_ExecuteRequest);
74      if (!s)
75           return 1;
76      rx_StartServer(0);
77      return 0;
78 }
79
80
81 /*extern int rx_socket;*/
82 extern unsigned short rx_port;
83 int do_rx_Init(void)
84 {
85      struct sockaddr_in s;
86      int len;
87
88      if (rx_Init(0)) {
89           fprintf(stderr, "Cannot initialize rx\n");
90           return 1;
91      }
92
93      len=sizeof(struct sockaddr_in);
94      if (getsockname(rx_socket, &s, &len)) {
95           perror("getsockname");
96           return 1;
97      }
98      rx_port=ntohs(s.sin_port);
99
100      return 0;
101 }
102
103 struct rx_securityClass *get_sc(char * cellname) 
104 {
105 #if 0
106      char realm[REALM_SZ];
107      CREDENTIALS c;
108 #endif
109      
110      return rxnull_NewClientSecurityObject();
111 #if 0     
112
113      ucstring(realm, cellname, REALM_SZ);
114      
115      if (krb_get_cred("afs", "", realm, &c)) {
116           if (get_ad_tkt("afs","",realm, DEFAULT_TKT_LIFE)) {
117                return NULL;
118           } else {
119                if (krb_get_cred("afs", "", realm, &c)) {
120                     return NULL;
121                }
122           }
123      }
124      
125      return rxkad_NewClientSecurityObject(rxkad_clear, c.session, c.kvno, 
126                                           c.ticket_st.length, c.ticket_st.dat);
127 #endif
128 }
129
130 #define scindex_NULL 0
131 #define scindex_RXKAD 2
132
133 #define scindex scindex_RXKAD
134 int main(int argc, char **argv) 
135 {
136      char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
137      afs_uint32 ssrv, dsrv;
138      char *databuffer,*srcf,*destd,*destf,*destpath;
139      struct stat statbuf;
140      
141      struct AFSStoreStatus sst;
142      struct AFSFetchStatus fst,dfst;
143      struct AFSVolSync vs;
144      struct AFSCallBack scb,dcb;
145      struct AFSFid sf, dd, df;
146     
147      int filesz;
148      int ch, blksize, bytesremaining, bytes;
149      struct timeval start, finish;
150      struct timezone tz;
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;
158
159      struct AFSCBFids theFids;
160      struct AFSCBs theCBs;
161
162
163      blksize=8*1024;
164      
165      while ((ch=getopt(argc, argv, "ioub:")) != -1) {
166           switch(ch)
167           {
168           case 'b':
169                blksize=atoi(optarg);
170                break;
171           case 'i':
172                slcl=1;
173                break;
174           case 'o':
175                dlcl=1;
176                break;
177           case 'a':
178                unauth=1;
179                break;
180           default:
181                exit(1);
182           }
183      }
184      
185
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");
192           exit(1);
193      }
194      srcf=argv[optind++];
195      destpath=argv[optind++];
196      destd=strdup(destpath);
197      if (!destd) {
198           perror("strdup");
199           exit(1);
200      }
201      if ((destf=strrchr(destd, '/'))) {
202           *destf++=0;
203      } else {
204           destf=destd;
205           destd=".";
206      }
207      
208      
209      if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
210           fprintf(stderr, "Cannot get attributes of %s\n", srcf);
211           exit(1);
212      }
213      if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
214           fprintf(stderr, "Cannot get attributes of %s\n", destd);
215           exit(1);
216      }
217     
218      if ((databuffer=malloc(blksize)) == NULL) {
219           perror("malloc");
220           exit(1);
221      }
222      
223      if (do_rx_Init())
224           exit(1);
225
226      if (start_cb_server()) {
227           printf("Cannot start callback service\n");
228           goto Fail_rx;
229      }
230      
231      if (!slcl) {
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);*/
237           }
238                sscindex=scindex_NULL;
239
240           if ((sconn=rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc, 
241                                       sscindex))
242                 ==NULL) {
243                struct in_addr s;
244                s.s_addr=ssrv;
245                printf("Cannot initialize rx connection to source server (%s)\n",
246                       inet_ntoa(s));
247                goto Fail_sc;
248           }
249      }
250      
251      if (!dlcl) {
252           if (!slcl && ssrv == dsrv) {
253                dconn=sconn;
254                dsc=NULL;
255           } else {
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);*/
262                     }
263                dscindex=scindex_NULL;
264                } else {
265                     dsc=ssc;
266                     dscindex=sscindex;
267                }
268           
269                if ((dconn=rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
270                                            dscindex))
271                    ==NULL) {
272                     struct in_addr s;
273                     s.s_addr=dsrv;
274                     printf("Cannot initialize rx connection to dest server (%s)\n",
275                            inet_ntoa(s));
276                     goto Fail_sconn;
277                }
278           }
279      }
280      
281      
282      memset(&sst, 0, sizeof(struct AFSStoreStatus));
283      
284      if (dlcl) {
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);
289                if (dfd < 0) {
290                     fprintf(stderr, "Cannot open %s (%s)\n", destpath,
291                             error_message(errno));
292                     goto Fail_dconn;
293                }
294           } else if (dfd < 0) {
295                fprintf(stderr, "Cannot open %s (%s)\n", destpath,
296                        error_message(errno));
297                goto Fail_dconn;
298           }
299      } else {
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",
306                                  destpath);
307                     else
308                          code=0;
309                } else {
310                     printf("Cannot create %s (%s)\n", destpath,
311                            error_message(code));
312                if (code)
313                     goto Fail_dconn;
314                }
315           }
316      }
317
318      if (slcl) {
319           sfd = open(srcf, O_RDONLY, 0);
320           if (sfd < 0) {
321                fprintf(stderr, "Cannot open %s (%s)\n", srcf,
322                        error_message(errno));
323                goto Fail_dconn;
324           }
325           if (fstat(sfd, &statbuf) < 0) {
326                fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
327                        error_message(errno));
328                close(sfd);
329                goto Fail_dconn;
330           }
331      } else {
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));
335                goto Fail_dconn;
336           }
337      }
338      
339      
340
341      if (slcl) {
342           filesz=statbuf.st_size;
343      } else {
344           filesz=fst.Length;
345      }
346      
347      printcallerrs=0;
348      fetchcode=0;
349      storecode=0;
350      if (!slcl) scall=rx_NewCall(sconn);
351      if (!dlcl) dcall=rx_NewCall(dconn);
352      gettimeofday(&start, &tz);
353      
354      if (!slcl) {
355           if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
356                printf("Unable to fetch data from %s (%s)\n", srcf, 
357                       error_message(code));
358                goto Fail_call;
359           }
360      }
361
362      if (!dlcl) {
363           if (slcl) {
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);
367           } else {
368                sst.Mask=AFS_SETMODTIME|AFS_SETMODE;
369                sst.ClientModTime=fst.ClientModTime;
370                sst.UnixModeBits=fst.UnixModeBits & ~(S_IFMT|S_ISUID|S_ISGID);
371           }
372      
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));
376                goto Fail_call;
377           }
378      }
379
380      if (slcl) {
381           bytesremaining=statbuf.st_size;
382      } else {
383           rx_Read(scall,&bytesremaining,sizeof(afs_int32));
384           bytesremaining=ntohl(bytesremaining);
385      }
386      
387      while (bytesremaining >0) {
388           /*printf("%d bytes remaining\n",bytesremaining);*/
389           if (slcl) {
390                if ((bytes=read(sfd, databuffer,
391                                   min(blksize,bytesremaining)))<= 0) {
392                     fetchcode=errno;
393                     break;
394                }
395           } else {
396                if ((bytes=rx_Read(scall, databuffer,
397                                   min(blksize,bytesremaining)))<= 0)
398                     break;
399           }
400           if (dlcl) {
401                if (write(dfd, databuffer, bytes) != bytes) {
402                     storecode=errno;
403                     break;
404                }
405           } else {
406                if (rx_Write(dcall, databuffer, bytes) != bytes)
407                     break;
408           }
409           bytesremaining -= bytes;
410           /*printf("%d bytes copied\n",bytes);*/
411      }
412           
413
414      if (bytesremaining > 0) {
415           printf("Some network error occured while copying data\n");
416           goto Fail_call;
417      }
418      
419      if (!slcl) fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
420      if (!dlcl) storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
421      printcallerrs=1;
422  Fail_call:
423           
424      if (slcl) {
425           if (close(sfd) && !fetchcode) fetchcode = errno;
426      } else {
427           fetchcode = rx_EndCall(scall, fetchcode);
428      }
429      if (fetchcode && printcallerrs)
430           printf("Error returned from fetch: %s\n", error_message(fetchcode));
431
432      if (dlcl) {
433           if (close(dfd) && !storecode) storecode = errno;
434      } else {
435           storecode = rx_EndCall(dcall, storecode);
436      }
437      if (storecode && printcallerrs)
438           printf("Error returned from store: %s\n", error_message(storecode));
439      
440      gettimeofday(&finish, &tz);
441      
442      if (!slcl) {
443           theFids.AFSCBFids_len=1;
444           theFids.AFSCBFids_val=&sf;
445           theCBs.AFSCBs_len=1;
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));
451      }
452
453      if (!dlcl) {
454           theFids.AFSCBFids_len=1;
455           theFids.AFSCBFids_val=&df;
456           theCBs.AFSCBs_len=1;
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));
462      }
463
464      if (code==0)
465           code=storecode;
466      if (code==0)
467           code=fetchcode;
468      
469  Fail_dconn:
470      if (!dlcl && (slcl || dconn != sconn))
471           rx_DestroyConnection(dconn);
472  Fail_sconn:
473      if (!slcl) rx_DestroyConnection(sconn);
474  Fail_sc:
475      if (dsc && dsc != ssc)
476           RXS_Close(dsc);
477      if (ssc) RXS_Close(ssc);
478  Fail_rx:
479      rx_Finalize();
480      
481      free(databuffer);
482      if (printcallerrs) {
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
486                       -start.tv_usec);
487           } else {
488                printf("Copied %d bytes in %d seconds\n", filesz, finish.tv_sec
489                       -start.tv_sec);
490           }
491           
492           size=filesz/1024.0;
493           time=finish.tv_sec-start.tv_sec + (finish.tv_usec-start.tv_usec)/1e+06;
494           rate=size/time;
495           printf("Transfer rate %g Kbytes/sec\n", rate);
496      
497      }
498      
499      exit(code != 0);
500 }