fs getserverprefs needs a larger buffer
[openafs.git] / src / venus / fs.c
index 0520ce1..e37a404 100644 (file)
@@ -10,9 +10,8 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
 
+#include <afs/afs_consts.h>
 #include <afs/afs_args.h>
 #include <rx/xdr.h>
 #include <sys/ioctl.h>
@@ -20,28 +19,24 @@ RCSID
 #include <netdb.h>
 #include <errno.h>
 #include <stdio.h>
+#include <ctype.h>
 #include <netinet/in.h>
 #include <sys/stat.h>
 #include <afs/stds.h>
 #include <afs/vice.h>
 #include <afs/venus.h>
+#include <afs/com_err.h>
+#include <afs/afs_consts.h>
 #ifdef AFS_AIX32_ENV
 #include <signal.h>
 #endif
 
-#ifdef HAVE_STRING_H
 #include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
 
 #undef VIRTUE
 #undef VICE
 #include "afs/prs_fs.h"
 #include <afs/afsint.h>
-#include <afs/auth.h>
 #include <afs/cellconfig.h>
 #include <ubik.h>
 #include <rx/rxkad.h>
@@ -51,41 +46,42 @@ RCSID
 #include <afs/vlserver.h>
 #include <afs/cmd.h>
 #include <afs/afsutil.h>
+#include <afs/com_err.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <afs/ptclient.h>
+#include <afs/ptuser.h>
+#include <afs/afsutil.h>
+#include <afs/sys_prototypes.h>
 
-
-#define        MAXHOSTS 13
-#define        OMAXHOSTS 8
-#define MAXCELLHOSTS 8
 #define MAXNAME 100
-#define        MAXSIZE 2048
 #define MAXINSIZE 1300         /* pioctl complains if data is larger than this */
 #define VMSGSIZE 128           /* size of msg buf in volume hdr */
 
-static char space[MAXSIZE];
+static char space[AFS_PIOCTL_MAXSIZE];
 static char tspace[1024];
 static struct ubik_client *uclient;
 
-static int GetClientAddrsCmd(), SetClientAddrsCmd(), FlushMountCmd();
-static int RxStatProcCmd(), RxStatPeerCmd(), GetFidCmd();
-
-extern char *hostutil_GetNameByINet();
-extern struct hostent *hostutil_GetHostByName();
-
+static int GetClientAddrsCmd(struct cmd_syndesc *, void *);
+static int SetClientAddrsCmd(struct cmd_syndesc *, void *);
+static int FlushMountCmd(struct cmd_syndesc *, void *);
+static int RxStatProcCmd(struct cmd_syndesc *, void *);
+static int RxStatPeerCmd(struct cmd_syndesc *, void *);
+static int GetFidCmd(struct cmd_syndesc *, void *);
+static int UuidCmd(struct cmd_syndesc *, void *);
 
-extern struct cmd_syndesc *cmd_CreateSyntax();
 static char pn[] = "fs";
 static int rxInitDone = 0;
 
-static void ZapList();
-static int PruneList();
-static CleanAcl();
-static SetVolCmd();
-static GetCellName();
-static VLDBInit();
-static void Die();
+struct AclEntry;
+struct Acl;
+static void ZapList(struct AclEntry *);
+static int PruneList(struct AclEntry **, int);
+static int CleanAcl(struct Acl *, char *);
+static int SetVolCmd(struct cmd_syndesc *as, void *arock);
+static int GetCellName(char *, struct afsconf_cell *);
+static int VLDBInit(int, struct afsconf_cell *);
+static void Die(int, char *);
 
 /*
  * Character to use between name and rights in printed representation for
@@ -120,8 +116,7 @@ struct vcxstat2 {
 };
 
 static void
-ZapAcl(acl)
-     struct Acl *acl;
+ZapAcl(struct Acl *acl)
 {
     if (!acl)
        return;
@@ -130,10 +125,8 @@ ZapAcl(acl)
     free(acl);
 }
 
-static
-foldcmp(a, b)
-     char *a;
-     char *b;
+static int
+foldcmp(char *a, char *b)
 {
     char t, u;
     while (1) {
@@ -286,6 +279,7 @@ PRights(afs_int32 arights, int dfs)
        if (arights & DFS_USR7)
            printf("H");
     }
+    return 0;
 }
 
 /* this function returns TRUE (1) if the file is in AFS, otherwise false (0) */
@@ -296,7 +290,7 @@ InAFS(char *apath)
     afs_int32 code;
 
     blob.in_size = 0;
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.out = space;
 
     code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
@@ -312,12 +306,15 @@ static char *
 Parent(char *apath)
 {
     char *tp;
-    strcpy(tspace, apath);
+    strlcpy(tspace, apath, sizeof(tspace));
     tp = strrchr(tspace, '/');
-    if (tp) {
-       *tp = 0;
-    } else
-       strcpy(tspace, ".");
+    if (tp == (char *)tspace)
+       tp++;
+    else if (tp == (char *)NULL) {
+       tp      = (char *)tspace;
+       *(tp++) = '.';
+    }
+    *tp = '\0';
     return tspace;
 }
 
@@ -652,11 +649,11 @@ QuickPrintStatus(VolumeStatus * status, char *name)
     printf("%-25.25s", name);
 
     if (status->MaxQuota != 0) {
-       printf("%10d%10d", status->MaxQuota, status->BlocksInUse);
+       printf(" %10d %10d", status->MaxQuota, status->BlocksInUse);
        QuotaUsed =
            ((((double)status->BlocksInUse) / status->MaxQuota) * 100.0);
     } else {
-       printf("  no limit%10d", status->BlocksInUse);
+       printf("   no limit %10d", status->BlocksInUse);
     }
     if (QuotaUsed > 90.0) {
        printf("%5.0f%%<<", QuotaUsed);
@@ -709,8 +706,8 @@ QuickPrintSpace(VolumeStatus * status, char *name)
 static char *
 AclToString(struct Acl *acl)
 {
-    static char mydata[MAXSIZE];
-    char tstring[MAXSIZE];
+    static char mydata[AFS_PIOCTL_MAXSIZE];
+    char tstring[AFS_PIOCTL_MAXSIZE];
     char dfsstring[30];
     struct AclEntry *tp;
 
@@ -731,7 +728,7 @@ AclToString(struct Acl *acl)
 }
 
 static int
-SetACLCmd(struct cmd_syndesc *as, char *arock)
+SetACLCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -749,7 +746,7 @@ SetACLCmd(struct cmd_syndesc *as, char *arock)
        clear = 0;
     plusp = !(as->parms[3].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = idf;
        blob.in = blob.out = space;
        code = pioctl(ti->data, VIOCGETAL, &blob, 1);
@@ -865,15 +862,13 @@ SetACLCmd(struct cmd_syndesc *as, char *arock)
 
 
 static int
-CopyACLCmd(struct cmd_syndesc *as, char *arock)
+CopyACLCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
     struct Acl *fa, *ta = 0;
     struct AclEntry *tp;
-    struct cmd_item *ti, *ui;
-    int plusp;
-    afs_int32 rights;
+    struct cmd_item *ti;
     int clear;
     int idf = getidf(as, parm_copyacl_id);
     int error = 0;
@@ -882,7 +877,7 @@ CopyACLCmd(struct cmd_syndesc *as, char *arock)
        clear = 1;
     else
        clear = 0;
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.in_size = idf;
     blob.in = blob.out = space;
     code = pioctl(as->parms[0].items->data, VIOCGETAL, &blob, 1);
@@ -893,7 +888,7 @@ CopyACLCmd(struct cmd_syndesc *as, char *arock)
     fa = ParseAcl(space);
     CleanAcl(fa, as->parms[0].items->data);
     for (ti = as->parms[1].items; ti; ti = ti->next) {
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = idf;
        blob.in = blob.out = space;
        code = pioctl(ti->data, VIOCGETAL, &blob, 1);
@@ -972,14 +967,14 @@ GetCell(char *fname, char *cellname)
  * negative sign), then it might be bad. We then query the ptserver
  * to see.
  */
-static
+static int
 BadName(char *aname, char *fname)
 {
     afs_int32 tc, code, id;
     char *nm;
     char cell[MAXCELLCHARS];
 
-    for (nm = aname; tc = *nm; nm++) {
+    for (nm = aname; (tc = *nm); nm++) {
        /* all must be '-' or digit to be bad */
        if (tc != '-' && (tc < '0' || tc > '9'))
            return 0;
@@ -1001,7 +996,7 @@ BadName(char *aname, char *fname)
 
 /* clean up an access control list of its bad entries; return 1 if we made
    any changes to the list, and 0 otherwise */
-static
+static int
 CleanAcl(struct Acl *aa, char *fname)
 {
     struct AclEntry *te, **le, *ne;
@@ -1045,7 +1040,7 @@ CleanAcl(struct Acl *aa, char *fname)
 
 /* clean up an acl to not have bogus entries */
 static int
-CleanACLCmd(struct cmd_syndesc *as, char *arock)
+CleanACLCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct Acl *ta = 0;
@@ -1057,7 +1052,7 @@ CleanACLCmd(struct cmd_syndesc *as, char *arock)
 
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = 0;
        blob.out = space;
        code = pioctl(ti->data, VIOCGETAL, &blob, 1);
@@ -1132,7 +1127,7 @@ CleanACLCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-ListACLCmd(struct cmd_syndesc *as, char *arock)
+ListACLCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct Acl *ta;
@@ -1144,7 +1139,7 @@ ListACLCmd(struct cmd_syndesc *as, char *arock)
 
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = idf;
        blob.in = blob.out = space;
        code = pioctl(ti->data, VIOCGETAL, &blob, 1);
@@ -1154,49 +1149,68 @@ ListACLCmd(struct cmd_syndesc *as, char *arock)
            continue;
        }
        ta = ParseAcl(space);
-       switch (ta->dfs) {
-       case 0:
-           printf("Access list for %s is\n", ti->data);
-           break;
-       case 1:
-           printf("DFS access list for %s is\n", ti->data);
-           break;
-       case 2:
-           printf("DFS initial directory access list of %s is\n", ti->data);
-           break;
-       case 3:
-           printf("DFS initial file access list of %s is\n", ti->data);
-           break;
-       }
-       if (ta->dfs) {
-           printf("  Default cell = %s\n", ta->cell);
-       }
-       if (ta->nplus > 0) {
-           if (!ta->dfs)
-               printf("Normal rights:\n");
-           for (te = ta->pluslist; te; te = te->next) {
-               printf("  %s ", te->name);
-               PRights(te->rights, ta->dfs);
-               printf("\n");
+        if (as->parms[3].items) {                      /* -cmd */
+            printf("fs setacl -dir %s -acl ", ti->data);
+            if (ta->nplus > 0) {
+                for (te = ta->pluslist; te; te = te->next) {
+                    printf("  %s ", te->name);
+                    PRights(te->rights, ta->dfs);
+                }
+            }
+            printf("\n");
+            if (ta->nminus > 0) {
+                printf("fs setacl -dir %s -acl ", ti->data);
+                for (te = ta->minuslist; te; te = te->next) {
+                    printf("  %s ", te->name);
+                    PRights(te->rights, ta->dfs);
+                }
+                printf(" -negative\n");
+            }
+        } else {
+           switch (ta->dfs) {
+           case 0:
+               printf("Access list for %s is\n", ti->data);
+               break;
+           case 1:
+               printf("DFS access list for %s is\n", ti->data);
+               break;
+           case 2:
+               printf("DFS initial directory access list of %s is\n", ti->data);
+               break;
+           case 3:
+               printf("DFS initial file access list of %s is\n", ti->data);
+               break;
            }
-       }
-       if (ta->nminus > 0) {
-           printf("Negative rights:\n");
-           for (te = ta->minuslist; te; te = te->next) {
-               printf("  %s ", te->name);
-               PRights(te->rights, ta->dfs);
-               printf("\n");
+           if (ta->dfs) {
+               printf("  Default cell = %s\n", ta->cell);
            }
+           if (ta->nplus > 0) {
+               if (!ta->dfs)
+                   printf("Normal rights:\n");
+               for (te = ta->pluslist; te; te = te->next) {
+                   printf("  %s ", te->name);
+                   PRights(te->rights, ta->dfs);
+                   printf("\n");
+               }
+           }
+           if (ta->nminus > 0) {
+               printf("Negative rights:\n");
+               for (te = ta->minuslist; te; te = te->next) {
+                   printf("  %s ", te->name);
+                   PRights(te->rights, ta->dfs);
+                   printf("\n");
+               }
+           }
+           if (ti->next)
+               printf("\n");
        }
-       if (ti->next)
-           printf("\n");
        ZapAcl(ta);
     }
     return error;
 }
 
 static int
-GetCallerAccess(struct cmd_syndesc *as, char *arock)
+GetCallerAccess(struct cmd_syndesc *as, void *arock)
 {
     struct cmd_item *ti;
     int error = 0;
@@ -1223,7 +1237,7 @@ GetCallerAccess(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-FlushVolumeCmd(struct cmd_syndesc *as, char *arock)
+FlushVolumeCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1244,8 +1258,108 @@ FlushVolumeCmd(struct cmd_syndesc *as, char *arock)
     return error;
 }
 
+/* 
+ * The Windows version of UuidCmd displays the UUID.
+ * When the UNIX version is updated to do the same
+ * be sure to replace the CMD_REQUIRED flag with
+ * CMD_OPTIONAL in the cmd_AddParam(-generate) call 
+ */
+static int
+UuidCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code;
+    struct ViceIoctl blob;
+
+    blob.in_size = 0;
+    blob.out_size = 0;
+    
+    if (as->parms[0].items) {
+        if (geteuid()) {
+            fprintf (stderr, "Permission denied: requires root access.\n");
+            return EACCES;
+        }
+
+        /* generate new UUID */
+        code = pioctl(0, VIOC_NEWUUID, &blob, 1);
+
+        if (code) {
+            Die(errno, 0);
+            return 1;
+        }
+
+        printf("New uuid generated.\n");
+    } else {
+        /* This will never execute */
+        printf("Please add the '-generate' option to generate a new UUID.\n");
+    }
+    return 0;
+}
+
+#if defined(AFS_CACHE_BYPASS)
+/*
+ * Set cache-bypass threshold.  Files larger than this size will not be cached.
+ * With a threshold of 0, the cache is always bypassed.  With a threshold of -1,
+ * cache bypass is disabled.
+ */
 static int
-FlushCmd(struct cmd_syndesc *as, char *arock)
+BypassThresholdCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code;
+    struct ViceIoctl blob;
+    afs_int32 threshold_i, threshold_o;
+    char *tp;  
+    
+    /* if new threshold supplied, then set and confirm, else,
+     * get current threshold and print
+     */
+        
+    if(as->parms[0].items) {
+       int digit, ix, len;
+                               
+       tp = as->parms[0].items->data;
+       len = strlen(tp);
+       digit = 1; 
+       for(ix = 0; ix < len; ++ix) {
+           if(!isdigit(tp[0])) {
+               digit = 0;
+               break;
+           }
+       }
+       if (digit == 0) {
+           fprintf(stderr, "fs bypassthreshold -size: %s must be an undecorated digit string.\n", tp);
+           return EINVAL;
+       }
+       threshold_i = atoi(tp);
+       if(ix > 9 && threshold_i < 2147483647) 
+           threshold_i = 2147483647;
+       blob.in = (char *) &threshold_i;
+       blob.in_size = sizeof(threshold_i);
+    } else {
+       blob.in = NULL;
+       blob.in_size = 0;
+    }
+
+    blob.out = (char *) &threshold_o;
+    blob.out_size = sizeof(threshold_o);
+    code = pioctl(0, VIOC_SETBYPASS_THRESH, &blob, 1);
+    if (code) {
+       Die(errno, NULL);
+       return 1;
+    } else {           
+       printf("Cache bypass threshold %d", threshold_o);
+       if(threshold_o ==  -1)
+           printf(" (disabled)");
+       printf("\n");
+    }
+
+    return 0;
+}
+
+#endif
+
+static int
+FlushCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1272,17 +1386,17 @@ FlushCmd(struct cmd_syndesc *as, char *arock)
 
 /* all this command does is repackage its args and call SetVolCmd */
 static int
-SetQuotaCmd(struct cmd_syndesc *as, char *arock)
+SetQuotaCmd(struct cmd_syndesc *as, void *arock)
 {
     struct cmd_syndesc ts;
 
     /* copy useful stuff from our command slot; we may later have to reorder */
     memcpy(&ts, as, sizeof(ts));       /* copy whole thing */
-    return SetVolCmd(&ts);
+    return SetVolCmd(&ts, arock);
 }
 
 static int
-SetVolCmd(struct cmd_syndesc *as, char *arock)
+SetVolCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1294,7 +1408,7 @@ SetVolCmd(struct cmd_syndesc *as, char *arock)
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
        /* once per file */
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = sizeof(*status) + 3;     /* for the three terminating nulls */
        blob.out = space;
        blob.in = space;
@@ -1302,7 +1416,7 @@ SetVolCmd(struct cmd_syndesc *as, char *arock)
        status->MinQuota = status->MaxQuota = -1;
        offmsg = NULL;
        if (as->parms[1].items) {
-           code = util_GetInt32(as->parms[1].items->data, &status->MaxQuota);
+           code = util_GetHumanInt32(as->parms[1].items->data, &status->MaxQuota);
            if (code) {
                fprintf(stderr, "%s: bad integer specified for quota.\n", pn);
                error = 1;
@@ -1346,7 +1460,7 @@ struct VenusFid {
 };
 
 static int
-ExamineCmd(struct cmd_syndesc *as, char *arock)
+ExamineCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1360,7 +1474,7 @@ ExamineCmd(struct cmd_syndesc *as, char *arock)
        struct VenusFid vfid;
 
        /* once per file */
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = 0;
        blob.out = space;
        code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
@@ -1387,7 +1501,7 @@ ExamineCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-ListQuotaCmd(struct cmd_syndesc *as, char *arock)
+ListQuotaCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1396,12 +1510,12 @@ ListQuotaCmd(struct cmd_syndesc *as, char *arock)
     char *name;
     int error = 0;
 
-    printf("%-25s%-10s%-10s%-7s%-11s\n", "Volume Name", "     Quota",
-          "      Used", " %Used", "  Partition");
+    printf("%-25s%-11s%-11s%-7s%-11s\n", "Volume Name", "      Quota",
+          "       Used", " %Used", "  Partition");
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
        /* once per file */
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = 0;
        blob.out = space;
        code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
@@ -1418,7 +1532,7 @@ ListQuotaCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-WhereIsCmd(struct cmd_syndesc *as, char *arock)
+WhereIsCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1431,7 +1545,7 @@ WhereIsCmd(struct cmd_syndesc *as, char *arock)
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
        /* once per file */
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = 0;
        blob.out = space;
        memset(space, 0, sizeof(space));
@@ -1444,7 +1558,7 @@ WhereIsCmd(struct cmd_syndesc *as, char *arock)
        hosts = (afs_int32 *) space;
        printf("File %s is on host%s ", ti->data,
               (hosts[0] && !hosts[1]) ? "" : "s");
-       for (j = 0; j < MAXHOSTS; j++) {
+       for (j = 0; j < AFS_MAXHOSTS; j++) {
            if (hosts[j] == 0)
                break;
            tp = hostutil_GetNameByINet(hosts[j]);
@@ -1457,7 +1571,7 @@ WhereIsCmd(struct cmd_syndesc *as, char *arock)
 
 
 static int
-DiskFreeCmd(struct cmd_syndesc *as, char *arock)
+DiskFreeCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1471,7 +1585,7 @@ DiskFreeCmd(struct cmd_syndesc *as, char *arock)
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
        /* once per file */
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = 0;
        blob.out = space;
        code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
@@ -1488,7 +1602,7 @@ DiskFreeCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-QuotaCmd(struct cmd_syndesc *as, char *arock)
+QuotaCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1500,7 +1614,7 @@ QuotaCmd(struct cmd_syndesc *as, char *arock)
     SetDotDefault(&as->parms[0].items);
     for (ti = as->parms[0].items; ti; ti = ti->next) {
        /* once per file */
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = 0;
        blob.out = space;
        code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
@@ -1521,7 +1635,7 @@ QuotaCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-ListMountCmd(struct cmd_syndesc *as, char *arock)
+ListMountCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1589,7 +1703,11 @@ ListMountCmd(struct cmd_syndesc *as, char *arock)
         * Find rightmost slash, if any.
         */
        last_component = (char *)strrchr(true_name, '/');
-       if (last_component) {
+       if (last_component == (char *)true_name) {
+           strcpy(parent_dir, "/");
+           last_component++;
+       }
+       else if (last_component != (char *)NULL) {
            /*
             * Found it.  Designate everything before it as the parent directory,
             * everything after it as the final component.
@@ -1619,9 +1737,9 @@ ListMountCmd(struct cmd_syndesc *as, char *arock)
 
        blob.in = last_component;
        blob.in_size = strlen(last_component) + 1;
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.out = space;
-       memset(space, 0, MAXSIZE);
+       memset(space, 0, AFS_PIOCTL_MAXSIZE);
 
        code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
 
@@ -1641,8 +1759,8 @@ ListMountCmd(struct cmd_syndesc *as, char *arock)
     return error;
 }
 
-static
-MakeMountCmd(struct cmd_syndesc *as, char *arock)
+static int
+MakeMountCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     char *cellName, *volName, *tmpName;
@@ -1675,7 +1793,7 @@ defect #3069
 
     /* Check for a cellname in the volume specification, and complain
      * if it doesn't match what was specified with -cell */
-    if (tmpName = strchr(volName, ':')) {
+    if ((tmpName = strchr(volName, ':'))) {
        *tmpName = '\0';
        if (cellName) {
            if (strcasecmp(cellName, volName)) {
@@ -1696,7 +1814,7 @@ defect #3069
 
     if (!cellName) {
        blob.in_size = 0;
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.out = space;
        code =
            pioctl(Parent(as->parms[0].items->data), VIOC_FILE_CELL_NAME,
@@ -1714,7 +1832,7 @@ defect #3069
        if (code == 0) {
            /* make the check.  Don't complain if there are problems with init */
            code =
-               ubik_Call(VL_GetEntryByNameO, uclient, 0, volName,
+               ubik_VL_GetEntryByNameO(uclient, 0, volName,
                          &vldbEntry);
            if (code == VL_NOENT) {
                fprintf(stderr,
@@ -1750,7 +1868,7 @@ defect #3069
  *      tp: Set to point to the actual name of the mount point to nuke.
  */
 static int
-RemoveMountCmd(struct cmd_syndesc *as, char *arock)
+RemoveMountCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code = 0;
     struct ViceIoctl blob;
@@ -1775,7 +1893,7 @@ RemoveMountCmd(struct cmd_syndesc *as, char *arock)
        blob.in_size = strlen(tp) + 1;
        blob.out = lsbuffer;
        blob.out_size = sizeof(lsbuffer);
-       code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 0);
+       code = pioctl(tbuffer, VIOC_AFS_STAT_MT_PT, &blob, 1);
        if (code) {
            if (errno == EINVAL) {
                fprintf(stderr, "%s: '%s' is not a mount point.\n", pn,
@@ -1789,7 +1907,7 @@ RemoveMountCmd(struct cmd_syndesc *as, char *arock)
        blob.out_size = 0;
        blob.in = tp;
        blob.in_size = strlen(tp) + 1;
-       code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
+       code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 1);
        if (code) {
            Die(errno, ti->data);
            error = 1;
@@ -1802,15 +1920,13 @@ RemoveMountCmd(struct cmd_syndesc *as, char *arock)
 */
 
 static int
-CheckServersCmd(struct cmd_syndesc *as, char *arock)
+CheckServersCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
     afs_int32 j;
     afs_int32 temp;
     char *tp;
-    char tbuffer[128];
-    afs_int32 interval;
     struct afsconf_cell info;
     struct chservinfo checkserv;
 
@@ -1818,7 +1934,7 @@ CheckServersCmd(struct cmd_syndesc *as, char *arock)
     blob.in_size = sizeof(struct chservinfo);
     blob.in = (caddr_t) & checkserv;
 
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.out = space;
     memset(space, 0, sizeof(afs_int32));       /* so we assure zero when nothing is copied back */
 
@@ -1901,23 +2017,21 @@ CheckServersCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-MessagesCmd(struct cmd_syndesc *as, char *arock)
+MessagesCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code = 0;
     struct ViceIoctl blob;
-    afs_int32 j;
-    afs_int32 temp;
     struct gaginfo gagflags;
     struct cmd_item *show;
 
     memset(&gagflags, 0, sizeof(struct gaginfo));
     blob.in_size = sizeof(struct gaginfo);
     blob.in = (caddr_t) & gagflags;
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.out = space;
     memset(space, 0, sizeof(afs_int32));       /* so we assure zero when nothing is copied back */
 
-    if (show = as->parms[0].items) {
+    if ((show = as->parms[0].items)) {
        if (!strcasecmp(show->data, "user"))
            gagflags.showflags |= GAGUSER;
        else if (!strcasecmp(show->data, "console"))
@@ -1947,7 +2061,7 @@ MessagesCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-CheckVolumesCmd(struct cmd_syndesc *as, char *arock)
+CheckVolumesCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1965,7 +2079,40 @@ CheckVolumesCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-SetCacheSizeCmd(struct cmd_syndesc *as, char *arock)
+PreCacheCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code;
+    struct ViceIoctl blob;
+    afs_int32 temp;
+    
+    if (!as->parms[0].items && !as->parms[1].items) {
+       fprintf(stderr, "%s: syntax error in precache cmd.\n", pn);
+       return 1;
+    }
+    if (as->parms[0].items) {
+       code = util_GetInt32(as->parms[0].items->data, &temp);
+       if (code) {
+           fprintf(stderr, "%s: bad integer specified for precache size.\n",
+                   pn);
+           return 1;
+       }
+    } else
+       temp = 0;
+    blob.in = (char *)&temp;
+    blob.in_size = sizeof(afs_int32);
+    blob.out_size = 0;
+    code = pioctl(0, VIOCPRECACHE, &blob, 1);
+    if (code) {
+       Die(errno, NULL);
+       return 1;
+    }
+    
+    printf("New precache size set.\n");
+    return 0;
+}
+
+static int
+SetCacheSizeCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -1976,7 +2123,7 @@ SetCacheSizeCmd(struct cmd_syndesc *as, char *arock)
        return 1;
     }
     if (as->parms[0].items) {
-       code = util_GetInt32(as->parms[0].items->data, &temp);
+       code = util_GetHumanInt32(as->parms[0].items->data, &temp);
        if (code) {
            fprintf(stderr, "%s: bad integer specified for cache size.\n",
                    pn);
@@ -2004,7 +2151,7 @@ SetCacheSizeCmd(struct cmd_syndesc *as, char *arock)
 
 #define MAXGCSIZE      16
 static int
-GetCacheParmsCmd(struct cmd_syndesc *as, char *arock)
+GetCacheParmsCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code, filesUsed;
     struct ViceIoctl blob;
@@ -2048,6 +2195,9 @@ GetCacheParmsCmd(struct cmd_syndesc *as, char *arock)
     printf("AFS using %5.0f%% of cache blocks (%d of %d 1k blocks)\n",
           percentBlocks, parms[1], parms[0]);
 
+    if (parms[2] == 0)
+       return 0;
+
     filesUsed = parms[2] - parms[3];
     percentFiles = ((double)filesUsed/parms[2]) * 100;
     printf("          %5.0f%% of the cache files (%d of %d files)\n",
@@ -2070,20 +2220,19 @@ GetCacheParmsCmd(struct cmd_syndesc *as, char *arock)
     }
 
     if (percentBlocks > 90)
-       printf("[cache size usage over 90%, consider increasing cache size]\n");
+       printf("[cache size usage over 90%%, consider increasing cache size]\n");
     if (percentFiles > 90)
-       printf("[cache file usage over 90%, consider increasing '-files' argument to afsd]\n");
+       printf("[cache file usage over 90%%, consider increasing '-files' argument to afsd]\n");
         
     return 0;
 }
 
 static int
-ListCellsCmd(struct cmd_syndesc *as, char *arock)
+ListCellsCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     afs_int32 i, j;
-    char *tcp, *tp;
-    afs_int32 clear;
+    char *tp;
     struct ViceIoctl blob;
     int resolve;
 
@@ -2092,7 +2241,7 @@ ListCellsCmd(struct cmd_syndesc *as, char *arock)
     for (i = 0;; i++) {
        tp = space;
        memcpy(tp, &i, sizeof(afs_int32));
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = sizeof(afs_int32);
        blob.in = space;
        blob.out = space;
@@ -2104,8 +2253,8 @@ ListCellsCmd(struct cmd_syndesc *as, char *arock)
            return 1;
        }
        tp = space;
-       printf("Cell %s on hosts", tp + MAXCELLHOSTS * sizeof(afs_int32));
-       for (j = 0; j < MAXCELLHOSTS; j++) {
+       printf("Cell %s on hosts", tp + AFS_MAXCELLHOSTS * sizeof(afs_int32));
+       for (j = 0; j < AFS_MAXCELLHOSTS; j++) {
            afs_int32 addr;
            char *name, tbuffer[20];
 
@@ -2129,7 +2278,7 @@ ListCellsCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-ListAliasesCmd(struct cmd_syndesc *as, char *arock)
+ListAliasesCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code, i;
     char *tp, *aliasName, *realName;
@@ -2138,7 +2287,7 @@ ListAliasesCmd(struct cmd_syndesc *as, char *arock)
     for (i = 0;; i++) {
        tp = space;
        memcpy(tp, &i, sizeof(afs_int32));
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.in_size = sizeof(afs_int32);
        blob.in = space;
        blob.out = space;
@@ -2159,14 +2308,13 @@ ListAliasesCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-CallBackRxConnCmd(struct cmd_syndesc *as, char *arock)
+CallBackRxConnCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
     struct cmd_item *ti;
     afs_int32 hostAddr;
     struct hostent *thp;
-    char *tp;
     int setp;
     
     ti = as->parms[0].items;
@@ -2198,7 +2346,38 @@ CallBackRxConnCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-NewCellCmd(struct cmd_syndesc *as, char *arock)
+NukeNFSCredsCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code;
+    struct ViceIoctl blob;
+    struct cmd_item *ti;
+    afs_int32 hostAddr;
+    struct hostent *thp;
+    
+    ti = as->parms[0].items;
+    thp = hostutil_GetHostByName(ti->data);
+    if (!thp) {
+       fprintf(stderr, "host %s not found in host table.\n", ti->data);
+       return 1;
+    }
+    else memcpy(&hostAddr, thp->h_addr, sizeof(afs_int32));
+    
+    /* now do operation */
+    blob.in_size = sizeof(afs_int32);
+    blob.out_size = sizeof(afs_int32);
+    blob.in = (char *) &hostAddr;
+    blob.out = (char *) &hostAddr;
+    
+    code = pioctl(0, VIOC_NFS_NUKE_CREDS, &blob, 1);
+    if (code < 0) {
+       Die(errno, 0);
+       return 1;
+    }
+    return 0;
+}
+
+static int
+NewCellCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code, linkedstate = 0, size = 0, *lp;
     struct ViceIoctl blob;
@@ -2206,12 +2385,12 @@ NewCellCmd(struct cmd_syndesc *as, char *arock)
     char *tp, *cellname = 0;
     struct hostent *thp;
     afs_int32 fsport = 0, vlport = 0;
-    afs_int32 magic, scount;   /* Number of servers to pass in pioctl call */
+    afs_int32 scount;          /* Number of servers to pass in pioctl call */
 
     /* Yuck!
      * With the NEWCELL pioctl call, 3.4 clients take an array of
-     * MAXHOSTS (13) servers while 3.5 clients take an array of
-     * MAXCELLHOSTS (8) servers. To determine which we are talking to,
+     * AFS_MAXHOSTS (13) servers while 3.5 clients take an array of
+     * AFS_MAXCELLHOSTS (8) servers. To determine which we are talking to,
      * do a GETCELL pioctl and pass it a magic number. If an array of
      * 8 comes back, its a 3.5 client. If not, its a 3.4 client.
      * If we get back EDOM, there are no cells in the kernel yet,
@@ -2221,7 +2400,7 @@ NewCellCmd(struct cmd_syndesc *as, char *arock)
     lp = (afs_int32 *) tp;
     *lp++ = 0;                 /* first cell entry */
     *lp = 0x12345678;          /* magic */
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.in_size = sizeof(afs_int32) + sizeof(afs_int32);
     blob.in = space;
     blob.out = space;
@@ -2231,11 +2410,11 @@ NewCellCmd(struct cmd_syndesc *as, char *arock)
        return 1;
     }
     if (code < 1 && errno == EDOM) {
-       scount = MAXHOSTS;
+       scount = AFS_MAXHOSTS;
     } else {
        tp = space;
-       cellname = tp + MAXCELLHOSTS * sizeof(afs_int32);
-       scount = ((cellname[0] != '\0') ? MAXCELLHOSTS : MAXHOSTS);
+       cellname = tp + AFS_MAXCELLHOSTS * sizeof(afs_int32);
+       scount = ((cellname[0] != '\0') ? AFS_MAXCELLHOSTS : AFS_MAXHOSTS);
     }
 
     /* Now setup and do the NEWCELL pioctl call */
@@ -2310,7 +2489,7 @@ NewCellCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-NewAliasCmd(struct cmd_syndesc *as, char *arock)
+NewAliasCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -2345,7 +2524,7 @@ NewAliasCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-WhichCellCmd(struct cmd_syndesc *as, char *arock)
+WhichCellCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct cmd_item *ti;
@@ -2370,14 +2549,14 @@ WhichCellCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-WSCellCmd(struct cmd_syndesc *as, char *arock)
+WSCellCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
 
     blob.in_size = 0;
     blob.in = NULL;
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.out = space;
 
     code = pioctl(NULL, VIOC_GET_WS_CELL, &blob, 1);
@@ -2400,7 +2579,7 @@ static PrimaryCellCmd(as)
 */
 
 static int
-MonitorCmd(struct cmd_syndesc *as, char *arock)
+MonitorCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -2461,7 +2640,7 @@ MonitorCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-SysNameCmd(struct cmd_syndesc *as, char *arock)
+SysNameCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -2472,13 +2651,13 @@ SysNameCmd(struct cmd_syndesc *as, char *arock)
     ti = as->parms[0].items;
     blob.in = space;
     blob.out = space;
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
     blob.in_size = sizeof(afs_int32);
     input += sizeof(afs_int32);
     for (; ti; ti = ti->next) {
        setp++;
        blob.in_size += strlen(ti->data) + 1;
-       if (blob.in_size > MAXSIZE) {
+       if (blob.in_size > AFS_PIOCTL_MAXSIZE) {
            fprintf(stderr, "%s: sysname%s too long.\n", pn,
                    setp > 1 ? "s" : "");
            return 1;
@@ -2515,13 +2694,13 @@ SysNameCmd(struct cmd_syndesc *as, char *arock)
 
 static char *exported_types[] = { "null", "nfs", "" };
 static int
-ExportAfsCmd(struct cmd_syndesc *as, char *arock)
+ExportAfsCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
     struct cmd_item *ti;
     int export = 0, type = 0, mode = 0, exp = 0, exportcall, pwsync =
-       0, smounts = 0;
+       0, smounts = 0, clipags = 0, pagcb = 0;
 
     ti = as->parms[0].items;
     if (strcmp(ti->data, "nfs") == 0)
@@ -2544,7 +2723,7 @@ ExportAfsCmd(struct cmd_syndesc *as, char *arock)
        }
        exp = 1;
     }
-    if (ti = as->parms[2].items) {     /* -noconvert */
+    if ((ti = as->parms[2].items)) {   /* -noconvert */
        if (strcmp(ti->data, "on") == 0)
            mode = 2;
        else if (strcmp(ti->data, "off") == 0)
@@ -2554,7 +2733,7 @@ ExportAfsCmd(struct cmd_syndesc *as, char *arock)
            return 1;
        }
     }
-    if (ti = as->parms[3].items) {     /* -uidcheck */
+    if ((ti = as->parms[3].items)) {   /* -uidcheck */
        if (strcmp(ti->data, "on") == 0)
            pwsync = 3;
        else if (strcmp(ti->data, "off") == 0)
@@ -2564,7 +2743,7 @@ ExportAfsCmd(struct cmd_syndesc *as, char *arock)
            return 1;
        }
     }
-    if (ti = as->parms[4].items) {     /* -submounts */
+    if ((ti = as->parms[4].items)) {   /* -submounts */
        if (strcmp(ti->data, "on") == 0)
            smounts = 3;
        else if (strcmp(ti->data, "off") == 0)
@@ -2574,8 +2753,29 @@ ExportAfsCmd(struct cmd_syndesc *as, char *arock)
            return 1;
        }
     }
+    if ((ti = as->parms[5].items)) {   /* -clipags */
+       if (strcmp(ti->data, "on") == 0)
+           clipags = 3;
+       else if (strcmp(ti->data, "off") == 0)
+           clipags = 2;
+       else {
+           fprintf(stderr, "Illegal argument %s\n", ti->data);
+           return 1;
+       }
+    }
+    if ((ti = as->parms[6].items)) {   /* -pagcb */
+       if (strcmp(ti->data, "on") == 0)
+           pagcb = 3;
+       else if (strcmp(ti->data, "off") == 0)
+           pagcb = 2;
+       else {
+           fprintf(stderr, "Illegal argument %s\n", ti->data);
+           return 1;
+       }
+    }
     exportcall =
-       (type << 24) | (mode << 6) | (pwsync << 4) | (smounts << 2) | export;
+       (type << 24) | (pagcb << 10) | (clipags << 8) |
+       (mode << 6) | (pwsync << 4) | (smounts << 2) | export;
     type &= ~0x70;
     /* make the call */
     blob.in = (char *)&exportcall;
@@ -2606,6 +2806,13 @@ ExportAfsCmd(struct cmd_syndesc *as, char *arock)
        printf("\t%s\n",
               (exportcall & 8 ? "Allow mounts of /afs/.. subdirs" :
                "Only mounts to /afs allowed"));
+       printf("\t%s\n",
+              (exportcall & 16 ? "Client-assigned PAG's are used" :
+               "Client-assigned PAG's are not used"));
+       printf("\t%s\n",
+              (exportcall & 32 ?
+               "Callbacks are made to get creds from new clients" :
+               "Callbacks are not made to get creds from new clients"));
     } else {
        printf("'%s' translator is disabled\n", exported_types[type]);
     }
@@ -2614,7 +2821,7 @@ ExportAfsCmd(struct cmd_syndesc *as, char *arock)
 
 
 static int
-GetCellCmd(struct cmd_syndesc *as, char *arock)
+GetCellCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -2665,7 +2872,7 @@ GetCellCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-SetCellCmd(struct cmd_syndesc *as, char *arock)
+SetCellCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -2743,7 +2950,7 @@ VLDBInit(int noAuthFlag, struct afsconf_cell *info)
 {
     afs_int32 code;
 
-    code = ugen_ClientInit(noAuthFlag, AFSDIR_CLIENT_ETC_DIRPATH, 
+    code = ugen_ClientInit(noAuthFlag, (char *) AFSDIR_CLIENT_ETC_DIRPATH,
                           info->name, 0, &uclient, 
                            NULL, pn, rxkad_clear,
                            VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
@@ -2805,7 +3012,6 @@ addServer(char *name, afs_int32 rank)
     struct setspref *ssp;
     struct spref *sp;
     struct hostent *thostent;
-    afs_uint32 addr;
     int error = 0;
 
 #ifndef MAXUSHORT
@@ -2841,7 +3047,7 @@ addServer(char *name, afs_int32 rank)
 
        if (debug)
            fprintf(stderr, "adding server %s, rank %d, ip addr 0x%lx\n",
-                   name, sp->rank, sp->server.s_addr);
+                   name, sp->rank, (long unsigned int) sp->server.s_addr);
     }
 
     return error;
@@ -2849,7 +3055,7 @@ addServer(char *name, afs_int32 rank)
 
 
 static int
-SetPrefCmd(struct cmd_syndesc *as, char *arock)
+SetPrefCmd(struct cmd_syndesc *as, void *arock)
 {
     FILE *infd;
     afs_int32 code;
@@ -2866,7 +3072,7 @@ SetPrefCmd(struct cmd_syndesc *as, char *arock)
     gblob.in_size = ((char *)&(ssp->servers[0])) - (char *)ssp;
     gblob.in = space;
     gblob.out = space;
-    gblob.out_size = MAXSIZE;
+    gblob.out_size = AFS_PIOCTL_MAXSIZE;
 
 
     if (geteuid()) {
@@ -2882,7 +3088,7 @@ SetPrefCmd(struct cmd_syndesc *as, char *arock)
            perror(ti->data);
            error = -1;
        } else {
-           while (fscanf(infd, "%79s%ld", name, &rank) != EOF) {
+           while (fscanf(infd, "%79s%ld", name, (long int *)&rank) != EOF) {
                code = addServer(name, (unsigned short)rank);
                if (code)
                    error = code;
@@ -2892,7 +3098,7 @@ SetPrefCmd(struct cmd_syndesc *as, char *arock)
 
     ti = as->parms[3].items;   /* -stdin */
     if (ti) {
-       while (scanf("%79s%ld", name, &rank) != EOF) {
+       while (scanf("%79s%ld", name, (long int *)&rank) != EOF) {
            code = addServer(name, (unsigned short)rank);
            if (code)
                error = code;
@@ -2955,12 +3161,12 @@ SetPrefCmd(struct cmd_syndesc *as, char *arock)
 
 
 static int
-GetPrefCmd(struct cmd_syndesc *as, char *arock)
+GetPrefCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct cmd_item *ti;
     char *name, tbuffer[20];
-    afs_int32 rank, addr;
+    afs_int32 addr;
     FILE *outfd;
     int resolve;
     int vlservers = 0;
@@ -2992,17 +3198,26 @@ GetPrefCmd(struct cmd_syndesc *as, char *arock)
        blob.in_size = sizeof(struct sprefrequest);
        blob.in = (char *)in;
        blob.out = space;
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
 
        in->num_servers =
-           (MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
+           (AFS_PIOCTL_MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
        in->flags = vlservers;
 
-       code = pioctl(0, VIOC_GETSPREFS, &blob, 1);
-       if (code) {
-           perror("getserverprefs pioctl");
-           return 1;
-       }
+       do {
+           code = pioctl(0, VIOC_GETSPREFS, &blob, 1);
+           if (code) {
+               if ((errno != E2BIG) || (2 * blob.out_size > 0x7FFF)) {
+                   perror("getserverprefs pioctl");
+                   return 1;
+               }
+               blob.out_size *= 2;
+               if (blob.out == space)
+                   blob.out = malloc(blob.out_size);
+               else
+                   blob.out = realloc(blob.out, blob.out_size);
+           }
+       } while (code != 0);
 
        out = (struct sprefinfo *)blob.out;
 
@@ -3021,11 +3236,14 @@ GetPrefCmd(struct cmd_syndesc *as, char *arock)
        in->offset = out->next_offset;
     } while (out->next_offset > 0);
 
+    if (blob.out != space)
+       free(blob.out);
+
     return 0;
 }
 
 static int
-StoreBehindCmd(struct cmd_syndesc *as, char *arock)
+StoreBehindCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code = 0;
     struct ViceIoctl blob;
@@ -3070,13 +3288,14 @@ StoreBehindCmd(struct cmd_syndesc *as, char *arock)
        verbose = 1;
 
     blob.in = (char *)&tsb;
-    blob.out = (char *)&tsb2;
-    blob.in_size = blob.out_size = sizeof(struct sbstruct);
-    memset(&tsb2, 0, sizeof(tsb2));
+    blob.in_size = sizeof(struct sbstruct);
 
     /* once per -file */
     for (ti = as->parms[1].items; ti; ti = ti->next) {
        /* Do this solely to see if the file is there */
+
+        blob.out = space;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
        code = pioctl(ti->data, VIOCWHEREIS, &blob, 1);
        if (code) {
            Die(errno, ti->data);
@@ -3084,6 +3303,9 @@ StoreBehindCmd(struct cmd_syndesc *as, char *arock)
            continue;
        }
 
+       memset(&tsb2, 0, sizeof(tsb2));
+       blob.out = (char *)&tsb2;
+       blob.out_size = sizeof(struct sbstruct);
        code = pioctl(ti->data, VIOC_STORBEHIND, &blob, 1);
        if (code) {
            Die(errno, ti->data);
@@ -3108,6 +3330,9 @@ StoreBehindCmd(struct cmd_syndesc *as, char *arock)
      */
     if (!as->parms[1].items || (allfiles != -1)) {
        tsb.sb_default = allfiles;
+        memset(&tsb2, 0, sizeof(tsb2));
+       blob.out = (char *)&tsb2;
+       blob.out_size = sizeof(struct sbstruct);
        code = pioctl(0, VIOC_STORBEHIND, &blob, 1);
        if (code) {
            Die(errno, ((allfiles == -1) ? 0 : "-allfiles"));
@@ -3125,8 +3350,8 @@ StoreBehindCmd(struct cmd_syndesc *as, char *arock)
 }
 
 
-static afs_int32
-SetCryptCmd(struct cmd_syndesc *as, char *arock)
+static int
+SetCryptCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code = 0, flag;
     struct ViceIoctl blob;
@@ -3152,8 +3377,8 @@ SetCryptCmd(struct cmd_syndesc *as, char *arock)
 }
 
 
-static afs_int32
-GetCryptCmd(struct cmd_syndesc *as, char *arock)
+static int
+GetCryptCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code = 0, flag;
     struct ViceIoctl blob;
@@ -3182,26 +3407,37 @@ GetCryptCmd(struct cmd_syndesc *as, char *arock)
 
 #ifdef AFS_DISCON_ENV
 static char *modenames[] = {
-    "discon",
-    "fetchonly",
-    "partial",
-    "nat",
-    "full",
+    "offline",
+    "online",
+    "readonly",  /* Not currently supported */
+    "fetchonly", /* Not currently supported */
+    "partial",   /* Not currently supported */
     NULL
 };
 
-static afs_int32
-DisconCmd(struct cmd_syndesc *as, char *arock)
+static char *policynames[] = {
+    "client",
+    "server",
+    "closer",  /* Not currently supported. */
+    "manual",  /* Not currently supported. */
+    NULL
+};
+
+static int
+DisconCmd(struct cmd_syndesc *as, void *arock)
 {
     struct cmd_item *ti;
     char *modename;
-    int modelen;
-    afs_int32 mode, code;
+    char *policyname;
+    int modelen, policylen;
+    afs_int32 mode, policy, code;
     struct ViceIoctl blob;
 
     blob.in = NULL;
     blob.in_size = 0;
 
+    space[0] = space[1] = space[2] = 0;
+
     ti = as->parms[0].items;
     if (ti) {
        modename = ti->data;
@@ -3212,11 +3448,30 @@ DisconCmd(struct cmd_syndesc *as, char *arock)
        if (modenames[mode] == NULL)
            printf("Unknown discon mode \"%s\"\n", modename);
        else {
-           memcpy(space, &mode, sizeof mode);
-           blob.in = space;
-           blob.in_size = sizeof mode;
+           space[0] = mode + 1;
        }
     }
+    ti = as->parms[1].items;
+    if (ti) {
+       policyname = ti->data;
+       policylen = strlen(policyname);
+       for (policy = 0; policynames[policy] != NULL; policy++)
+           if (!strncasecmp(policyname, policynames[policy], policylen))
+               break;
+       if (policynames[policy] == NULL)
+           printf("Unknown discon mode \"%s\"\n", policyname);
+       else {
+           space[1] = policy + 1;
+       }
+    }
+
+    if (as->parms[2].items) {
+       space[2] = 1;
+       printf("force on\n");
+    }
+
+    blob.in = space;
+    blob.in_size = 3 * sizeof(afs_int32);
 
     blob.out_size = sizeof(mode);
     blob.out = space;
@@ -3259,17 +3514,17 @@ main(int argc, char **argv)
 #endif
 
     /* try to find volume location information */
-    ts = cmd_CreateSyntax("getclientaddrs", GetClientAddrsCmd, 0,
+    ts = cmd_CreateSyntax("getclientaddrs", GetClientAddrsCmd, NULL,
                          "get client network interface addresses");
     cmd_CreateAlias(ts, "gc");
 
-    ts = cmd_CreateSyntax("setclientaddrs", SetClientAddrsCmd, 0,
+    ts = cmd_CreateSyntax("setclientaddrs", SetClientAddrsCmd, NULL,
                          "set client network interface addresses");
     cmd_AddParm(ts, "-address", CMD_LIST, CMD_OPTIONAL | CMD_EXPANDS,
                "client network interfaces");
     cmd_CreateAlias(ts, "sc");
 
-    ts = cmd_CreateSyntax("setserverprefs", SetPrefCmd, 0,
+    ts = cmd_CreateSyntax("setserverprefs", SetPrefCmd, NULL,
                          "set server ranks");
     cmd_AddParm(ts, "-servers", CMD_LIST, CMD_OPTIONAL | CMD_EXPANDS,
                "fileserver names and ranks");
@@ -3280,7 +3535,7 @@ main(int argc, char **argv)
     cmd_AddParm(ts, "-stdin", CMD_FLAG, CMD_OPTIONAL, "input from stdin");
     cmd_CreateAlias(ts, "sp");
 
-    ts = cmd_CreateSyntax("getserverprefs", GetPrefCmd, 0,
+    ts = cmd_CreateSyntax("getserverprefs", GetPrefCmd, NULL,
                          "get server ranks");
     cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_OPTIONAL,
                "output to named file");
@@ -3289,7 +3544,7 @@ main(int argc, char **argv)
 /*    cmd_AddParm(ts, "-cell", CMD_FLAG, CMD_OPTIONAL, "cellname"); */
     cmd_CreateAlias(ts, "gp");
 
-    ts = cmd_CreateSyntax("setacl", SetACLCmd, 0, "set access control list");
+    ts = cmd_CreateSyntax("setacl", SetACLCmd, NULL, "set access control list");
     cmd_AddParm(ts, "-dir", CMD_LIST, 0, "directory");
     cmd_AddParm(ts, "-acl", CMD_LIST, 0, "access list entries");
     cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, "clear access list");
@@ -3302,24 +3557,25 @@ main(int argc, char **argv)
                "initial file acl (DFS only)");
     cmd_CreateAlias(ts, "sa");
 
-    ts = cmd_CreateSyntax("listacl", ListACLCmd, 0,
+    ts = cmd_CreateSyntax("listacl", ListACLCmd, NULL,
                          "list access control list");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     parm_listacl_id = ts->nParms;
     cmd_AddParm(ts, "-id", CMD_FLAG, CMD_OPTIONAL, "initial directory acl");
     cmd_AddParm(ts, "-if", CMD_FLAG, CMD_OPTIONAL, "initial file acl");
+    cmd_AddParm(ts, "-cmd", CMD_FLAG, CMD_OPTIONAL, "output as 'fs setacl' command");
     cmd_CreateAlias(ts, "la");
 
-    ts = cmd_CreateSyntax("getcalleraccess", GetCallerAccess, 0,
+    ts = cmd_CreateSyntax("getcalleraccess", GetCallerAccess, NULL,
             "list callers access");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     cmd_CreateAlias(ts, "gca");
 
-    ts = cmd_CreateSyntax("cleanacl", CleanACLCmd, 0,
+    ts = cmd_CreateSyntax("cleanacl", CleanACLCmd, NULL,
                          "clean up access control list");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
-    ts = cmd_CreateSyntax("copyacl", CopyACLCmd, 0,
+    ts = cmd_CreateSyntax("copyacl", CopyACLCmd, NULL,
                          "copy access control list");
     cmd_AddParm(ts, "-fromdir", CMD_SINGLE, 0,
                "source directory (or DFS file)");
@@ -3333,13 +3589,13 @@ main(int argc, char **argv)
 
     cmd_CreateAlias(ts, "ca");
 
-    ts = cmd_CreateSyntax("flush", FlushCmd, 0, "flush file from cache");
+    ts = cmd_CreateSyntax("flush", FlushCmd, NULL, "flush file from cache");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
-    ts = cmd_CreateSyntax("flushmount", FlushMountCmd, 0,
+    ts = cmd_CreateSyntax("flushmount", FlushMountCmd, NULL,
                          "flush mount symlink from cache");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
-    ts = cmd_CreateSyntax("setvol", SetVolCmd, 0, "set volume status");
+    ts = cmd_CreateSyntax("setvol", SetVolCmd, NULL, "set volume status");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     cmd_AddParm(ts, "-max", CMD_SINGLE, CMD_OPTIONAL,
                "disk space quota in 1K units");
@@ -3352,32 +3608,32 @@ main(int argc, char **argv)
                "offline message");
     cmd_CreateAlias(ts, "sv");
 
-    ts = cmd_CreateSyntax("messages", MessagesCmd, 0,
+    ts = cmd_CreateSyntax("messages", MessagesCmd, NULL,
                          "control Cache Manager messages");
     cmd_AddParm(ts, "-show", CMD_SINGLE, CMD_OPTIONAL,
                "[user|console|all|none]");
 
-    ts = cmd_CreateSyntax("examine", ExamineCmd, 0, "display file/volume status");
+    ts = cmd_CreateSyntax("examine", ExamineCmd, NULL, "display file/volume status");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     cmd_CreateAlias(ts, "lv");
     cmd_CreateAlias(ts, "listvol");
 
-    ts = cmd_CreateSyntax("listquota", ListQuotaCmd, 0, "list volume quota");
+    ts = cmd_CreateSyntax("listquota", ListQuotaCmd, NULL, "list volume quota");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     cmd_CreateAlias(ts, "lq");
 
-    ts = cmd_CreateSyntax("diskfree", DiskFreeCmd, 0,
+    ts = cmd_CreateSyntax("diskfree", DiskFreeCmd, NULL,
                          "show server disk space usage");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     cmd_CreateAlias(ts, "df");
 
-    ts = cmd_CreateSyntax("quota", QuotaCmd, 0, "show volume quota usage");
+    ts = cmd_CreateSyntax("quota", QuotaCmd, NULL, "show volume quota usage");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
-    ts = cmd_CreateSyntax("lsmount", ListMountCmd, 0, "list mount point");
+    ts = cmd_CreateSyntax("lsmount", ListMountCmd, NULL, "list mount point");
     cmd_AddParm(ts, "-dir", CMD_LIST, 0, "directory");
 
-    ts = cmd_CreateSyntax("mkmount", MakeMountCmd, 0, "make mount point");
+    ts = cmd_CreateSyntax("mkmount", MakeMountCmd, NULL, "make mount point");
     cmd_AddParm(ts, "-dir", CMD_SINGLE, 0, "directory");
     cmd_AddParm(ts, "-vol", CMD_SINGLE, 0, "volume name");
     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
@@ -3385,6 +3641,12 @@ main(int argc, char **argv)
     cmd_AddParm(ts, "-fast", CMD_FLAG, CMD_OPTIONAL,
                "don't check name with VLDB");
 
+#if defined(AFS_CACHE_BYPASS)
+       ts = cmd_CreateSyntax("bypassthreshold", BypassThresholdCmd, 0,
+               "get/set cache bypass file size threshold");
+       cmd_AddParm(ts, "-size", CMD_SINGLE, CMD_OPTIONAL, "file size");
+#endif
+
 /*
 
 defect 3069
@@ -3393,10 +3655,10 @@ defect 3069
 */
 
 
-    ts = cmd_CreateSyntax("rmmount", RemoveMountCmd, 0, "remove mount point");
+    ts = cmd_CreateSyntax("rmmount", RemoveMountCmd, NULL, "remove mount point");
     cmd_AddParm(ts, "-dir", CMD_LIST, 0, "directory");
 
-    ts = cmd_CreateSyntax("checkservers", CheckServersCmd, 0,
+    ts = cmd_CreateSyntax("checkservers", CheckServersCmd, NULL,
                          "check local cell's servers");
     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell to check");
     cmd_AddParm(ts, "-all", CMD_FLAG, CMD_OPTIONAL, "check all cells");
@@ -3405,12 +3667,12 @@ defect 3069
     cmd_AddParm(ts, "-interval", CMD_SINGLE, CMD_OPTIONAL,
                "seconds between probes");
 
-    ts = cmd_CreateSyntax("checkvolumes", CheckVolumesCmd, 0,
+    ts = cmd_CreateSyntax("checkvolumes", CheckVolumesCmd, NULL,
                          "check volumeID/name mappings");
     cmd_CreateAlias(ts, "checkbackups");
 
 
-    ts = cmd_CreateSyntax("setcachesize", SetCacheSizeCmd, 0,
+    ts = cmd_CreateSyntax("setcachesize", SetCacheSizeCmd, NULL,
                          "set cache size");
     cmd_AddParm(ts, "-blocks", CMD_SINGLE, CMD_OPTIONAL,
                "size in 1K byte blocks (0 => reset)");
@@ -3419,19 +3681,19 @@ defect 3069
     cmd_AddParm(ts, "-reset", CMD_FLAG, CMD_OPTIONAL,
                "reset size back to boot value");
 
-    ts = cmd_CreateSyntax("getcacheparms", GetCacheParmsCmd, 0,
+    ts = cmd_CreateSyntax("getcacheparms", GetCacheParmsCmd, NULL,
                          "get cache usage info");
     cmd_AddParm(ts, "-files", CMD_FLAG, CMD_OPTIONAL, "Show cach files used as well");
     cmd_AddParm(ts, "-excessive", CMD_FLAG, CMD_OPTIONAL, "excessively verbose cache stats");
 
-    ts = cmd_CreateSyntax("listcells", ListCellsCmd, 0,
+    ts = cmd_CreateSyntax("listcells", ListCellsCmd, NULL,
                          "list configured cells");
     cmd_AddParm(ts, "-numeric", CMD_FLAG, CMD_OPTIONAL, "addresses only");
 
-    ts = cmd_CreateSyntax("listaliases", ListAliasesCmd, 0,
+    ts = cmd_CreateSyntax("listaliases", ListAliasesCmd, NULL,
                          "list configured cell aliases");
 
-    ts = cmd_CreateSyntax("setquota", SetQuotaCmd, 0, "set volume quota");
+    ts = cmd_CreateSyntax("setquota", SetQuotaCmd, NULL, "set volume quota");
     cmd_AddParm(ts, "-path", CMD_SINGLE, CMD_OPTIONAL, "dir/file path");
     cmd_AddParm(ts, "-max", CMD_SINGLE, 0, "max quota in kbytes");
 #ifdef notdef
@@ -3439,13 +3701,13 @@ defect 3069
 #endif
     cmd_CreateAlias(ts, "sq");
 
-    ts = cmd_CreateSyntax("newcell", NewCellCmd, 0, "configure new cell");
+    ts = cmd_CreateSyntax("newcell", NewCellCmd, NULL, "configure new cell");
     cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "cell name");
     cmd_AddParm(ts, "-servers", CMD_LIST, CMD_REQUIRED, "primary servers");
     cmd_AddParm(ts, "-linkedcell", CMD_SINGLE, CMD_OPTIONAL,
                "linked cell name");
 
-    ts = cmd_CreateSyntax("newalias", NewAliasCmd, 0,
+    ts = cmd_CreateSyntax("newalias", NewAliasCmd, NULL,
                          "configure new cell alias");
     cmd_AddParm(ts, "-alias", CMD_SINGLE, 0, "alias name");
     cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "real name of cell");
@@ -3463,42 +3725,42 @@ defect 3069
                "cell's vldb server port");
 #endif
 
-    ts = cmd_CreateSyntax("whichcell", WhichCellCmd, 0, "list file's cell");
+    ts = cmd_CreateSyntax("whichcell", WhichCellCmd, NULL, "list file's cell");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
-    ts = cmd_CreateSyntax("whereis", WhereIsCmd, 0, "list file's location");
+    ts = cmd_CreateSyntax("whereis", WhereIsCmd, NULL, "list file's location");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
-    ts = cmd_CreateSyntax("wscell", WSCellCmd, 0, "list workstation's cell");
+    ts = cmd_CreateSyntax("wscell", WSCellCmd, NULL, "list workstation's cell");
 
 /*
-    ts = cmd_CreateSyntax("primarycell", PrimaryCellCmd, 0, "obsolete (listed primary cell)");
+    ts = cmd_CreateSyntax("primarycell", PrimaryCellCmd, NULL, "obsolete (listed primary cell)");
 */
 
     /* set cache monitor host address */
-    ts = cmd_CreateSyntax("monitor", MonitorCmd, 0, (char *)CMD_HIDDEN);
+    ts = cmd_CreateSyntax("monitor", MonitorCmd, NULL, (char *)CMD_HIDDEN);
     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL,
                "host name or 'off'");
     cmd_CreateAlias(ts, "mariner");
 
-    ts = cmd_CreateSyntax("getcellstatus", GetCellCmd, 0, "get cell status");
+    ts = cmd_CreateSyntax("getcellstatus", GetCellCmd, NULL, "get cell status");
     cmd_AddParm(ts, "-cell", CMD_LIST, 0, "cell name");
 
-    ts = cmd_CreateSyntax("setcell", SetCellCmd, 0, "set cell status");
+    ts = cmd_CreateSyntax("setcell", SetCellCmd, NULL, "set cell status");
     cmd_AddParm(ts, "-cell", CMD_LIST, 0, "cell name");
     cmd_AddParm(ts, "-suid", CMD_FLAG, CMD_OPTIONAL, "allow setuid programs");
     cmd_AddParm(ts, "-nosuid", CMD_FLAG, CMD_OPTIONAL,
                "disallow setuid programs");
 
-    ts = cmd_CreateSyntax("flushvolume", FlushVolumeCmd, 0,
+    ts = cmd_CreateSyntax("flushvolume", FlushVolumeCmd, NULL,
                          "flush all data in volume");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
-    ts = cmd_CreateSyntax("sysname", SysNameCmd, 0,
+    ts = cmd_CreateSyntax("sysname", SysNameCmd, NULL,
                          "get/set sysname (i.e. @sys) value");
     cmd_AddParm(ts, "-newsys", CMD_LIST, CMD_OPTIONAL, "new sysname");
 
-    ts = cmd_CreateSyntax("exportafs", ExportAfsCmd, 0,
+    ts = cmd_CreateSyntax("exportafs", ExportAfsCmd, NULL,
                          "enable/disable translators to AFS");
     cmd_AddParm(ts, "-type", CMD_SINGLE, 0, "exporter name");
     cmd_AddParm(ts, "-start", CMD_SINGLE, CMD_OPTIONAL,
@@ -3509,9 +3771,13 @@ defect 3069
                "run on strict 'uid check' mode (on | off)");
     cmd_AddParm(ts, "-submounts", CMD_SINGLE, CMD_OPTIONAL,
                "allow nfs mounts to subdirs of /afs/.. (on  | off)");
+    cmd_AddParm(ts, "-clipags", CMD_SINGLE, CMD_OPTIONAL,
+               "enable use of client-assigned PAG's (on  | off)");
+    cmd_AddParm(ts, "-pagcb", CMD_SINGLE, CMD_OPTIONAL,
+               "enable callbacks to get creds from new clients (on  | off)");
 
 
-    ts = cmd_CreateSyntax("storebehind", StoreBehindCmd, 0,
+    ts = cmd_CreateSyntax("storebehind", StoreBehindCmd, NULL,
                          "store to server after file close");
     cmd_AddParm(ts, "-kbytes", CMD_SINGLE, CMD_OPTIONAL,
                "asynchrony for specified names");
@@ -3521,39 +3787,52 @@ defect 3069
     cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "show status");
     cmd_CreateAlias(ts, "sb");
 
-    ts = cmd_CreateSyntax("setcrypt", SetCryptCmd, 0,
+    ts = cmd_CreateSyntax("setcrypt", SetCryptCmd, NULL,
                          "set cache manager encryption flag");
     cmd_AddParm(ts, "-crypt", CMD_SINGLE, 0, "on or off");
 
-    ts = cmd_CreateSyntax("getcrypt", GetCryptCmd, 0,
+    ts = cmd_CreateSyntax("getcrypt", GetCryptCmd, NULL,
                          "get cache manager encryption flag");
 
-    ts = cmd_CreateSyntax("rxstatproc", RxStatProcCmd, 0,
+    ts = cmd_CreateSyntax("rxstatproc", RxStatProcCmd, NULL,
                          "Manage per process RX statistics");
     cmd_AddParm(ts, "-enable", CMD_FLAG, CMD_OPTIONAL, "Enable RX stats");
     cmd_AddParm(ts, "-disable", CMD_FLAG, CMD_OPTIONAL, "Disable RX stats");
     cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, "Clear RX stats");
 
-    ts = cmd_CreateSyntax("rxstatpeer", RxStatPeerCmd, 0,
+    ts = cmd_CreateSyntax("rxstatpeer", RxStatPeerCmd, NULL,
                          "Manage per peer RX statistics");
     cmd_AddParm(ts, "-enable", CMD_FLAG, CMD_OPTIONAL, "Enable RX stats");
     cmd_AddParm(ts, "-disable", CMD_FLAG, CMD_OPTIONAL, "Disable RX stats");
     cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, "Clear RX stats");
 
-    ts = cmd_CreateSyntax("setcbaddr", CallBackRxConnCmd, 0, "configure callback connection address");
+    ts = cmd_CreateSyntax("setcbaddr", CallBackRxConnCmd, NULL, "configure callback connection address");
     cmd_AddParm(ts, "-addr", CMD_SINGLE, CMD_OPTIONAL, "host name or address");
 
     /* try to find volume location information */
-    ts = cmd_CreateSyntax("getfid", GetFidCmd, 0,
+    ts = cmd_CreateSyntax("getfid", GetFidCmd, NULL,
                          "get fid for file(s)");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
 #ifdef AFS_DISCON_ENV
-    ts = cmd_CreateSyntax("discon", DisconCmd, 0,
+    ts = cmd_CreateSyntax("discon", DisconCmd, NULL,
                          "disconnection mode");
-    cmd_AddParm(ts, "-mode", CMD_SINGLE, CMD_OPTIONAL, "nat | full");
+    cmd_AddParm(ts, "-mode", CMD_SINGLE, CMD_REQUIRED, "offline | online");
+    cmd_AddParm(ts, "-policy", CMD_SINGLE, CMD_OPTIONAL, "client | server");
+    cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "Force reconnection, despite any synchronization issues.");
 #endif
 
+    ts = cmd_CreateSyntax("nukenfscreds", NukeNFSCredsCmd, NULL, "nuke credentials for NFS client");
+    cmd_AddParm(ts, "-addr", CMD_SINGLE, 0, "host name or address");
+
+    ts = cmd_CreateSyntax("uuid", UuidCmd, NULL, "manage the UUID for the cache manager");
+    cmd_AddParm(ts, "-generate", CMD_FLAG, CMD_REQUIRED, "generate a new UUID");
+
+    ts = cmd_CreateSyntax("precache", PreCacheCmd, 0,
+                         "set precache size");
+    cmd_AddParm(ts, "-blocks", CMD_SINGLE, CMD_OPTIONAL,
+               "size in 1K byte blocks (0 => disable)");
+
     code = cmd_Dispatch(argc, argv);
     if (rxInitDone)
        rx_Finalize();
@@ -3599,18 +3878,16 @@ Die(int errnum, char *filename)
            fprintf(stderr, "%s:'%s'", pn, filename);
        else
            fprintf(stderr, "%s", pn);
-       fprintf(stderr, ": %s\n", error_message(errnum));
+       fprintf(stderr, ": %s\n", afs_error_message(errnum));
        break;
     }
 }
 
 /* get clients interface addresses */
 static int
-GetClientAddrsCmd(struct cmd_syndesc *as, char *arock)
+GetClientAddrsCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
-    struct cmd_item *ti;
-    char *name;
     struct ViceIoctl blob;
     struct sprefrequest *in;
     struct sprefinfo *out;
@@ -3622,10 +3899,10 @@ GetClientAddrsCmd(struct cmd_syndesc *as, char *arock)
        blob.in_size = sizeof(struct sprefrequest);
        blob.in = (char *)in;
        blob.out = space;
-       blob.out_size = MAXSIZE;
+       blob.out_size = AFS_PIOCTL_MAXSIZE;
 
        in->num_servers =
-           (MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
+           (AFS_PIOCTL_MAXSIZE - 2 * sizeof(short)) / sizeof(struct spref);
        /* returns addr in network byte order */
        code = pioctl(0, VIOC_GETCPREFS, &blob, 1);
        if (code) {
@@ -3652,15 +3929,14 @@ GetClientAddrsCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-SetClientAddrsCmd(struct cmd_syndesc *as, char *arock)
+SetClientAddrsCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code, addr;
     struct cmd_item *ti;
-    char name[80];
     struct ViceIoctl blob;
     struct setspref *ssp;
     int sizeUsed = 0, i, flag;
-    afs_int32 existingAddr[1024];      /* existing addresses on this host */
+    afs_uint32 existingAddr[1024];     /* existing addresses on this host */
     int existNu;
     int error = 0;
 
@@ -3668,7 +3944,7 @@ SetClientAddrsCmd(struct cmd_syndesc *as, char *arock)
     ssp->num_servers = 0;
     blob.in = space;
     blob.out = space;
-    blob.out_size = MAXSIZE;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
 
     if (geteuid()) {
        fprintf(stderr, "Permission denied: requires root access.\n");
@@ -3726,7 +4002,7 @@ SetClientAddrsCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-FlushMountCmd(struct cmd_syndesc *as, char *arock)
+FlushMountCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     struct ViceIoctl blob;
@@ -3794,7 +4070,11 @@ FlushMountCmd(struct cmd_syndesc *as, char *arock)
         * Find rightmost slash, if any.
         */
        last_component = (char *)strrchr(true_name, '/');
-       if (last_component) {
+       if (last_component == (char *)true_name) {
+           strcpy(parent_dir, "/");
+           last_component++;
+       }
+       else if (last_component != (char *)NULL) {
            /*
             * Found it.  Designate everything before it as the parent directory,
             * everything after it as the final component.
@@ -3825,7 +4105,7 @@ FlushMountCmd(struct cmd_syndesc *as, char *arock)
        blob.in = last_component;
        blob.in_size = strlen(last_component) + 1;
        blob.out_size = 0;
-       memset(space, 0, MAXSIZE);
+       memset(space, 0, AFS_PIOCTL_MAXSIZE);
 
        code = pioctl(parent_dir, VIOC_AFS_FLUSHMOUNT, &blob, 1);
 
@@ -3842,12 +4122,11 @@ FlushMountCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-RxStatProcCmd(struct cmd_syndesc *as, char *arock)
+RxStatProcCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     afs_int32 flags = 0;
     struct ViceIoctl blob;
-    struct cmd_item *ti;
 
     if (as->parms[0].items) {  /* -enable */
        flags |= AFSCALL_RXSTATS_ENABLE;
@@ -3877,12 +4156,11 @@ RxStatProcCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-RxStatPeerCmd(struct cmd_syndesc *as, char *arock)
+RxStatPeerCmd(struct cmd_syndesc *as, void *arock)
 {
     afs_int32 code;
     afs_int32 flags = 0;
     struct ViceIoctl blob;
-    struct cmd_item *ti;
 
     if (as->parms[0].items) {  /* -enable */
        flags |= AFSCALL_RXSTATS_ENABLE;
@@ -3912,7 +4190,7 @@ RxStatPeerCmd(struct cmd_syndesc *as, char *arock)
 }
 
 static int
-GetFidCmd(struct cmd_syndesc *as, char *arock)
+GetFidCmd(struct cmd_syndesc *as, void *arock)
 {
     struct ViceIoctl blob;
     struct cmd_item *ti;