Make tests/afcp compile cleanly
[openafs.git] / src / tests / afscp.c
index 41189dd..717e705 100644 (file)
@@ -9,16 +9,22 @@
 #include <fcntl.h>
 #include <sys/select.h>
 #include <sys/stat.h>
+#include <netdb.h>
 
 #include <afs/param.h>
 #include <afs/afsint.h>
+#define FSINT_COMMON_XG 1
+#include <afs/afscbint.h>
 #include <sys/ioctl.h>
 #include <afs/venus.h>
 #include <afs/cellconfig.h>
-#include <afs/afs.h>
+#include <afs/sys_prototypes.h>
+
+#include <afs/afs_consts.h>
 
 /*#include <rx/rxkad.h>*/
 #include <rx/rx_null.h>
+#include <rx/rx_prototypes.h>
 
 /*#include <krb.h>*/
 #include <afs/com_err.h>
@@ -34,9 +40,61 @@ statfile(char *path, char *cellname, afs_uint32 * server, struct AFSFid *f)
 
     struct ViceIoctl v;
     struct VenusFid vf;
-    afs_int32 srvbuf[MAXHOSTS];
+    afs_int32 srvbuf[AFS_MAXHOSTS];
     int code;
 
+    if (!strncmp(path, "@afs:", 5)) {
+       char *pdup, *p;
+       struct hostent *he;
+
+       pdup = strdup(path);
+       strtok(pdup, ":");
+
+       if (!(p = strtok(NULL, ":"))) {
+           free(pdup);
+           return -1;
+       }
+       strncpy(cellname, p, MAXCELLCHARS);
+
+       if (!(p = strtok(NULL, ":"))) {
+           free(pdup);
+           return -1;
+       }
+       he = gethostbyname(p);
+       if (!he) {
+           printf("Unknown host %s\n", p);
+           free(pdup);
+           return -1;
+       }
+       memcpy(server, he->h_addr, he->h_length);
+
+       if (!(p = strtok(NULL, ":"))) {
+           free(pdup);
+           return -1;
+       }
+       f->Volume = atoi(p);
+
+       if (!(p = strtok(NULL, ":"))) {
+           free(pdup);
+           return -1;
+       }
+       f->Vnode = atoi(p);
+
+       if (!(p = strtok(NULL, ":"))) {
+           free(pdup);
+           return -1;
+       }
+       f->Unique = atoi(p);
+
+       if (strtok(NULL, ":")) {
+           printf("Too much extra stuff after @afs:...\n");
+           free(pdup);
+           return -1;
+       }
+
+       return 0;
+    }
+
     v.in = 0;
     v.in_size = 0;
     v.out = cellname;
@@ -62,11 +120,10 @@ statfile(char *path, char *cellname, afs_uint32 * server, struct AFSFid *f)
 }
 
 
-extern int RXAFSCB_ExecuteRequest();
 struct rx_securityClass *sc;
 
 extern int
-start_cb_server()
+start_cb_server(void)
 {
     struct rx_service *s;
 
@@ -93,7 +150,7 @@ do_rx_Init(void)
     }
 
     len = sizeof(struct sockaddr_in);
-    if (getsockname(rx_socket, &s, &len)) {
+    if (getsockname(rx_socket, (struct sockaddr *)&s, (socklen_t *)&len)) {
        perror("getsockname");
        return 1;
     }
@@ -139,7 +196,7 @@ main(int argc, char **argv)
 {
     char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
     afs_uint32 ssrv, dsrv;
-    char *databuffer, *srcf, *destd, *destf, *destpath;
+    char *databuffer, *srcf = NULL, *destd = NULL, *destf = NULL, *destpath = NULL;
     struct stat statbuf;
 
     struct AFSStoreStatus sst;
@@ -148,17 +205,17 @@ main(int argc, char **argv)
     struct AFSCallBack scb, dcb;
     struct AFSFid sf, dd, df;
 
-    int filesz;
+    int filesz = 0;
     int ch, blksize, bytesremaining, bytes;
     struct timeval start, finish;
     struct timezone tz;
     struct rx_securityClass *ssc = 0, *dsc = 0;
     int sscindex, dscindex;
-    struct rx_connection *sconn, *dconn;
-    struct rx_call *scall, *dcall;
-    int code, fetchcode, storecode, printcallerrs;
-    int slcl = 0, dlcl = 0;
-    int sfd, dfd, unauth = 0;
+    struct rx_connection *sconn = NULL, *dconn = NULL;
+    struct rx_call *scall = NULL, *dcall = NULL;
+    int code = 0, fetchcode, storecode, printcallerrs = 0;
+    int slcl = 0, dlcl = 0, unlock = 0;
+    int sfd = 0, dfd = 0, unauth = 0;
 
     struct AFSCBFids theFids;
     struct AFSCBs theCBs;
@@ -166,7 +223,7 @@ main(int argc, char **argv)
 
     blksize = 8 * 1024;
 
-    while ((ch = getopt(argc, argv, "ioub:")) != -1) {
+    while ((ch = getopt(argc, argv, "iouUb:")) != -1) {
        switch (ch) {
        case 'b':
            blksize = atoi(optarg);
@@ -177,44 +234,54 @@ main(int argc, char **argv)
        case 'o':
            dlcl = 1;
            break;
-       case 'a':
+       case 'u':
            unauth = 1;
            break;
+       case 'U':
+           unlock = 1;
+           break;
        default:
+           printf("Unknown option '%c'\n", ch);
            exit(1);
        }
     }
 
 
-    if (argc - optind < 2) {
+    if (argc - optind + unlock < 2) {
        fprintf(stderr,
-               "Usage: afscp [-i|-o]] [-b xfersz] [-u] source dest\n");
+               "Usage: afscp [-i|-o]] [-b xfersz] [-u] [-U] source [dest]\n");
        fprintf(stderr, "  -b   Set block size\n");
        fprintf(stderr, "  -i   Source is local (copy into AFS)\n");
        fprintf(stderr, "  -o   Dest is local (copy out of AFS)\n");
        fprintf(stderr, "  -u   Run unauthenticated\n");
+       fprintf(stderr, "  -U   Send an unlock request for source. (dest path not required)\n");
+       fprintf(stderr, "source and dest can be paths or specified as:\n");
+       fprintf(stderr, "     @afs:cellname:servername:volume:vnode:uniq\n");
        exit(1);
     }
     srcf = argv[optind++];
-    destpath = argv[optind++];
-    destd = strdup(destpath);
-    if (!destd) {
-       perror("strdup");
-       exit(1);
-    }
-    if ((destf = strrchr(destd, '/'))) {
-       *destf++ = 0;
-    } else {
-       destf = destd;
-       destd = ".";
+    if (!unlock) {
+       destpath = argv[optind++];
+       destd = strdup(destpath);
+       if (!destd) {
+           perror("strdup");
+           exit(1);
+       }
+       if ((destf = strrchr(destd, '/'))) {
+           *destf++ = 0;
+       } else {
+           destf = destd;
+           destd = ".";
+       }
+    } else if (slcl) {
+       fprintf(stderr, "-i and -U cannot be used together\n");
     }
 
-
     if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
        fprintf(stderr, "Cannot get attributes of %s\n", srcf);
        exit(1);
     }
-    if (!dlcl && statfile(destd, dcell, &dsrv, &dd)) {
+    if (!unlock && !dlcl && statfile(destd, dcell, &dsrv, &dd)) {
        fprintf(stderr, "Cannot get attributes of %s\n", destd);
        exit(1);
     }
@@ -253,7 +320,7 @@ main(int argc, char **argv)
        }
     }
 
-    if (!dlcl) {
+    if (!dlcl && !unlock) {
        if (!slcl && ssrv == dsrv) {
            dconn = sconn;
            dsc = NULL;
@@ -288,22 +355,22 @@ main(int argc, char **argv)
 
     memset(&sst, 0, sizeof(struct AFSStoreStatus));
 
-    if (dlcl) {
+    if (dlcl && !unlock) {
        dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666);
        if (dfd < 0 && errno == EEXIST) {
            printf("%s already exists, overwriting\n", destpath);
            dfd = open(destpath, O_RDWR | O_TRUNC, 0666);
            if (dfd < 0) {
                fprintf(stderr, "Cannot open %s (%s)\n", destpath,
-                       error_message(errno));
+                       afs_error_message(errno));
                goto Fail_dconn;
            }
        } else if (dfd < 0) {
            fprintf(stderr, "Cannot open %s (%s)\n", destpath,
-                   error_message(errno));
+                   afs_error_message(errno));
            goto Fail_dconn;
        }
-    } else {
+    } else if (!unlock) {
        if ((code =
             RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb,
                              &vs))) {
@@ -316,7 +383,7 @@ main(int argc, char **argv)
                    code = 0;
            } else {
                printf("Cannot create %s (%s)\n", destpath,
-                      error_message(code));
+                      afs_error_message(code));
                if (code)
                    goto Fail_dconn;
            }
@@ -327,19 +394,19 @@ main(int argc, char **argv)
        sfd = open(srcf, O_RDONLY, 0);
        if (sfd < 0) {
            fprintf(stderr, "Cannot open %s (%s)\n", srcf,
-                   error_message(errno));
+                   afs_error_message(errno));
            goto Fail_dconn;
        }
        if (fstat(sfd, &statbuf) < 0) {
            fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
-                   error_message(errno));
+                   afs_error_message(errno));
            close(sfd);
            goto Fail_dconn;
        }
     } else {
        if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
            printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
-                  error_message(code));
+                  afs_error_message(code));
            goto Fail_dconn;
        }
     }
@@ -355,16 +422,29 @@ main(int argc, char **argv)
     printcallerrs = 0;
     fetchcode = 0;
     storecode = 0;
-    if (!slcl)
+    if (!slcl && !unlock)
        scall = rx_NewCall(sconn);
-    if (!dlcl)
+    if (!dlcl && !unlock)
        dcall = rx_NewCall(dconn);
     gettimeofday(&start, &tz);
+    if (unlock) {
+       if (fst.lockCount) {
+           printf("Sending 1 unlock for %s (%d locks)\n", srcf, fst.lockCount);
+           if ((code = RXAFS_ReleaseLock(sconn, &sf, &vs))) {
+               printf("Unable to unlock %s (%s)\n", srcf,
+                      afs_error_message(code));
+           }
+       } else {
+           printf("No locks for %s\n", srcf);
+       }
+       fetchcode = code;
+       goto Finish;
+    }
 
     if (!slcl) {
        if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
            printf("Unable to fetch data from %s (%s)\n", srcf,
-                  error_message(code));
+                  afs_error_message(code));
            goto Fail_call;
        }
     }
@@ -385,7 +465,7 @@ main(int argc, char **argv)
        if ((code =
             StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
            printf("Unable to store data to %s (%s)\n", destpath,
-                  error_message(code));
+                  afs_error_message(code));
            goto Fail_call;
        }
     }
@@ -393,7 +473,7 @@ main(int argc, char **argv)
     if (slcl) {
        bytesremaining = statbuf.st_size;
     } else {
-       rx_Read(scall, &bytesremaining, sizeof(afs_int32));
+       rx_Read(scall, (char *)&bytesremaining, sizeof(afs_int32));
        bytesremaining = ntohl(bytesremaining);
     }
 
@@ -444,17 +524,17 @@ main(int argc, char **argv)
        fetchcode = rx_EndCall(scall, fetchcode);
     }
     if (fetchcode && printcallerrs)
-       printf("Error returned from fetch: %s\n", error_message(fetchcode));
+       printf("Error returned from fetch: %s\n", afs_error_message(fetchcode));
 
     if (dlcl) {
        if (close(dfd) && !storecode)
            storecode = errno;
-    } else {
+    } else if (!unlock) {
        storecode = rx_EndCall(dcall, storecode);
     }
     if (storecode && printcallerrs)
-       printf("Error returned from store: %s\n", error_message(storecode));
-
+       printf("Error returned from store: %s\n", afs_error_message(storecode));
+Finish:
     gettimeofday(&finish, &tz);
 
     if (!slcl) {
@@ -465,7 +545,7 @@ main(int argc, char **argv)
        scb.CallBackType = CB_DROPPED;
        if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
            printf("Could not give up source callback: %s\n",
-                  error_message(code));
+                  afs_error_message(code));
     }
 
     if (!dlcl) {
@@ -476,7 +556,7 @@ main(int argc, char **argv)
        dcb.CallBackType = CB_DROPPED;
        if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
            printf("Could not give up target callback: %s\n",
-                  error_message(code));
+                  afs_error_message(code));
     }
 
     if (code == 0)
@@ -485,7 +565,7 @@ main(int argc, char **argv)
        code = fetchcode;
 
   Fail_dconn:
-    if (!dlcl && (slcl || dconn != sconn))
+    if (!dlcl && !unlock && (slcl || dconn != sconn))
        rx_DestroyConnection(dconn);
   Fail_sconn:
     if (!slcl)
@@ -499,14 +579,14 @@ main(int argc, char **argv)
     rx_Finalize();
 
     free(databuffer);
-    if (printcallerrs) {
+    if (printcallerrs && !unlock) {
        double rate, size, time;
        if (finish.tv_sec == start.tv_sec) {
            printf("Copied %d bytes in %d microseconds\n", filesz,
                   finish.tv_usec - start.tv_usec);
        } else {
            printf("Copied %d bytes in %d seconds\n", filesz,
-                  finish.tv_sec - start.tv_sec);
+                  (int)(finish.tv_sec - start.tv_sec));
        }
 
        size = filesz / 1024.0;