fs: display cell not available on ESRCH
[openafs.git] / src / venus / fs.c
index 8cc842f..4329434 100644 (file)
@@ -12,8 +12,8 @@
 #include <afs/stds.h>
 
 #include <roken.h>
-
 #include <ctype.h>
+#include <assert.h>
 
 #include <afs/afs_consts.h>
 #include <afs/afs_args.h>
@@ -67,7 +67,6 @@ 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 *);
 
 /*
@@ -297,7 +296,7 @@ Parent(char *apath)
     tp = strrchr(tspace, '/');
     if (tp == (char *)tspace)
        tp++;
-    else if (tp == (char *)NULL) {
+    else if (tp == NULL) {
        tp      = (char *)tspace;
        *(tp++) = '.';
     }
@@ -460,10 +459,10 @@ SetDotDefault(struct cmd_item **aitemp)
     if (*aitemp)
        return;                 /* already has value */
     /* otherwise, allocate an item representing "." */
-    ti = (struct cmd_item *)malloc(sizeof(struct cmd_item));
+    ti = malloc(sizeof(struct cmd_item));
     assert(ti);
     ti->next = (struct cmd_item *)0;
-    ti->data = (char *)malloc(2);
+    ti->data = malloc(2);
     assert(ti->data);
     strcpy(ti->data, ".");
     *aitemp = ti;
@@ -500,7 +499,7 @@ ChangeList(struct Acl *al, afs_int32 plus, char *aname, afs_int32 arights,
         return;                 /* can't reduce non-existing rights   */
 
     /* Otherwise we make a new item and plug in the new data. */
-    tlist = (struct AclEntry *)malloc(sizeof(struct AclEntry));
+    tlist = malloc(sizeof(struct AclEntry));
     assert(tlist);
     strcpy(tlist->name, aname);
     tlist->rights = arights;
@@ -573,12 +572,12 @@ EmptyAcl(char *astr)
     struct Acl *tp;
     int junk;
 
-    tp = (struct Acl *)malloc(sizeof(struct Acl));
+    tp = malloc(sizeof(struct Acl));
     assert(tp);
     tp->nplus = tp->nminus = 0;
     tp->pluslist = tp->minuslist = 0;
     tp->dfs = 0;
-    sscanf(astr, "%d dfs:%d %s", &junk, &tp->dfs, tp->cell);
+    sscanf(astr, "%d dfs:%d %1024s", &junk, &tp->dfs, tp->cell);
     return tp;
 }
 
@@ -590,10 +589,10 @@ ParseAcl(char *astr)
     struct AclEntry *first, *last, *tl;
     struct Acl *ta;
 
-    ta = (struct Acl *)malloc(sizeof(struct Acl));
+    ta = malloc(sizeof(struct Acl));
     assert(ta);
     ta->dfs = 0;
-    sscanf(astr, "%d dfs:%d %s", &ta->nplus, &ta->dfs, ta->cell);
+    sscanf(astr, "%d dfs:%d %1024s", &ta->nplus, &ta->dfs, ta->cell);
     astr = SkipLine(astr);
     sscanf(astr, "%d", &ta->nminus);
     astr = SkipLine(astr);
@@ -604,9 +603,9 @@ ParseAcl(char *astr)
     last = 0;
     first = 0;
     for (i = 0; i < nplus; i++) {
-       sscanf(astr, "%100s %d", tname, &trights);
+       sscanf(astr, "%99s %d", tname, &trights);
        astr = SkipLine(astr);
-       tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
+       tl = malloc(sizeof(struct AclEntry));
        assert(tl);
        if (!first)
            first = tl;
@@ -622,9 +621,9 @@ ParseAcl(char *astr)
     last = 0;
     first = 0;
     for (i = 0; i < nminus; i++) {
-       sscanf(astr, "%100s %d", tname, &trights);
+       sscanf(astr, "%99s %d", tname, &trights);
        astr = SkipLine(astr);
-       tl = (struct AclEntry *)malloc(sizeof(struct AclEntry));
+       tl = malloc(sizeof(struct AclEntry));
        assert(tl);
        if (!first)
            first = tl;
@@ -1315,6 +1314,25 @@ FlushVolumeCmd(struct cmd_syndesc *as, void *arock)
     return error;
 }
 
+static int
+FlushAllVolumesCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code;
+    struct ViceIoctl blob;
+    int error = 0;
+
+    blob.in_size = 0;
+    blob.out_size = AFS_PIOCTL_MAXSIZE;
+    blob.out = space;
+
+    code = pioctl(NULL, VIOC_FLUSHALL, &blob, 0);
+    if (code) {
+       fprintf(stderr, "Error flushing all volumes\n");
+       error = 1;
+    }
+    return error;
+}
+
 /*
  * The Windows version of UuidCmd displays the UUID.
  * When the UNIX version is updated to do the same
@@ -1708,14 +1726,17 @@ static int
 GetLastComponent(const char *data, char **outdir, char **outbase,
                 int *thru_symlink)
 {
-    char orig_name[1024];      /*Original name, may be modified */
-    char true_name[1024];      /*``True'' dirname (e.g., symlink target) */
+    char orig_name[MAXPATHLEN];        /*Original name, may be modified */
+    char true_name[MAXPATHLEN];        /*``True'' dirname (e.g., symlink target) */
     char *lastSlash;
     struct stat statbuff;      /*Buffer for status info */
     int link_chars_read;       /*Num chars read in readlink() */
     char *dirname = NULL;
     char *basename = NULL;
 
+    *outbase = NULL;
+    *outdir = NULL;
+
     if (thru_symlink)
        *thru_symlink = 0;
 
@@ -1737,8 +1758,8 @@ GetLastComponent(const char *data, char **outdir, char **outbase,
        if (thru_symlink)
             *thru_symlink = 1;
 
-       /* Read name of resolved file */
-       link_chars_read = readlink(orig_name, true_name, 1024);
+       /* Read name of resolved file (leave space for NULL!) */
+       link_chars_read = readlink(orig_name, true_name, MAXPATHLEN-1);
        if (link_chars_read <= 0) {
            fprintf(stderr,
                    "%s: Can't read target name for '%s' symbolic link!\n",
@@ -1800,10 +1821,10 @@ GetLastComponent(const char *data, char **outdir, char **outbase,
     return 0;
 
 out:
-    if (outdir)
-       free(outdir);
-    if (outbase)
-       free(outbase);
+    if (dirname)
+       free(dirname);
+    if (basename)
+       free(basename);
     return -1;
 }
 
@@ -1834,7 +1855,6 @@ ListMountCmd(struct cmd_syndesc *as, void *arock)
 
        code = pioctl(parent_dir, VIOC_AFS_STAT_MT_PT, &blob, 1);
        free(last_component);
-       free(parent_dir);
 
        if (code == 0) {
            printf("'%s' is a %smount point for volume '%s'\n", ti->data,
@@ -1848,6 +1868,7 @@ ListMountCmd(struct cmd_syndesc *as, void *arock)
            }
            error = 1;
        }
+       free(parent_dir);
     }
     return error;
 }
@@ -1860,6 +1881,7 @@ MakeMountCmd(struct cmd_syndesc *as, void *arock)
     struct afsconf_cell info;
     struct vldbentry vldbEntry;
     struct ViceIoctl blob;
+    struct afsconf_dir *dir;
 
 /*
 
@@ -1909,19 +1931,40 @@ defect #3069
        blob.in_size = 0;
        blob.out_size = AFS_PIOCTL_MAXSIZE;
        blob.out = space;
-       code =
-           pioctl(Parent(as->parms[0].items->data), VIOC_FILE_CELL_NAME,
-                  &blob, 1);
+       code = pioctl(Parent(as->parms[0].items->data), VIOC_FILE_CELL_NAME,
+                     &blob, 1);
+       if (code) {
+          fprintf(stderr,
+                  "%s: couldn't get cell name for file's parent\n", pn);
+          return 1;
+       }
+    }
+
+    dir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
+    if (!dir) {
+       fprintf(stderr,
+               "Could not process files in configuration directory (%s).\n",
+               AFSDIR_CLIENT_ETC_DIRPATH);
+        return 1;
     }
 
-    code = GetCellName(cellName ? cellName : space, &info);
+    code = afsconf_GetCellInfo(dir, cellName ? cellName : space,
+                              AFSCONF_VLDBSERVICE, &info);
     if (code) {
+       fprintf(stderr,
+               "%s: cell %s not in %s\n", pn, cellName ? cellName : space,
+               AFSDIR_CLIENT_CELLSERVDB_FILEPATH);
        return 1;
     }
+
     if (!(as->parms[4].items)) {
        /* not fast, check which cell the mountpoint is being created in */
-       /* not fast, check name with VLDB */
-       code = VLDBInit(1, &info);
+       code = ugen_ClientInitCell(dir, &info,
+                                  AFSCONF_SECOPTS_FALLBACK_NULL |
+                                  AFSCONF_SECOPTS_NOAUTH,
+                                  &uclient, VLDB_MAXSERVERS,
+                                  AFSCONF_VLDBSERVICE, 50);
+
        if (code == 0) {
            /* make the check.  Don't complain if there are problems with init */
            code =
@@ -3033,25 +3076,10 @@ GetCellName(char *cellName, struct afsconf_cell *info)
     return 0;
 }
 
-
-static int
-VLDBInit(int noAuthFlag, struct afsconf_cell *info)
-{
-    afs_int32 code;
-
-    code = ugen_ClientInit(noAuthFlag, (char *) AFSDIR_CLIENT_ETC_DIRPATH,
-                          info->name, 0, &uclient,
-                           NULL, pn, rxkad_clear,
-                           VLDB_MAXSERVERS, AFSCONF_VLDBSERVICE, 50,
-                           0, 0, USER_SERVICE_ID);
-    rxInitDone = 1;
-    return code;
-}
-
 static struct ViceIoctl gblob;
 static int debug = 0;
 /*
- * here follow some routines in suport of the setserverprefs and
+ * here follow some routines in support of the setserverprefs and
  * getserverprefs commands.  They are:
  * SetPrefCmd  "top-level" routine
  * addServer   adds a server to the list of servers to be poked into the
@@ -3150,7 +3178,7 @@ SetPrefCmd(struct cmd_syndesc *as, void *arock)
     afs_int32 code;
     struct cmd_item *ti;
     char name[80];
-    afs_int32 rank;
+    int rank;
     struct setspref *ssp;
     int error = 0;             /* -1 means error message printed,
                                 * >0 means errno value for unprinted message */
@@ -3177,7 +3205,7 @@ SetPrefCmd(struct cmd_syndesc *as, void *arock)
            perror(ti->data);
            error = -1;
        } else {
-           while (fscanf(infd, "%79s%ld", name, (long int *)&rank) != EOF) {
+           while (fscanf(infd, "%79s%d", name, &rank) != EOF) {
                code = addServer(name, (unsigned short)rank);
                if (code)
                    error = code;
@@ -3187,7 +3215,7 @@ SetPrefCmd(struct cmd_syndesc *as, void *arock)
 
     ti = as->parms[3].items;   /* -stdin */
     if (ti) {
-       while (scanf("%79s%ld", name, (long int *)&rank) != EOF) {
+       while (scanf("%79s%d", name, &rank) != EOF) {
            code = addServer(name, (unsigned short)rank);
            if (code)
                error = code;
@@ -3342,6 +3370,7 @@ StoreBehindCmd(struct cmd_syndesc *as, void *arock)
     afs_int32 allfiles;
     char *t;
     int error = 0;
+    int async_default = -1;
 
     tsb.sb_thisfile = -1;
     ti = as->parms[0].items;   /* -kbytes */
@@ -3402,14 +3431,18 @@ StoreBehindCmd(struct cmd_syndesc *as, void *arock)
            continue;
        }
 
-       if (verbose && (blob.out_size == sizeof(tsb2))) {
-           if (tsb2.sb_thisfile == -1) {
-               fprintf(stdout, "Will store %s according to default.\n",
-                       ti->data);
+       if (blob.out_size == sizeof(tsb2)) {
+           async_default = tsb2.sb_default;
+
+           if (verbose) {
+               if (tsb2.sb_thisfile == -1) {
+                   fprintf(stdout, "Will store %s according to default.\n",
+                           ti->data);
            } else {
-               fprintf(stdout,
-                       "Will store up to %d kbytes of %s asynchronously.\n",
-                       (tsb2.sb_thisfile / 1024), ti->data);
+                   fprintf(stdout,
+                           "Will store up to %d kbytes of %s asynchronously.\n",
+                           (tsb2.sb_thisfile / 1024), ti->data);
+               }
            }
        }
     }
@@ -3417,7 +3450,7 @@ StoreBehindCmd(struct cmd_syndesc *as, void *arock)
     /* If no files - make at least one pioctl call, or
      * set the allfiles default if we need to.
      */
-    if (!as->parms[1].items || (allfiles != -1)) {
+    if (async_default < 0 || (allfiles != -1)) {
        tsb.sb_default = allfiles;
         memset(&tsb2, 0, sizeof(tsb2));
        blob.out = (char *)&tsb2;
@@ -3426,13 +3459,16 @@ StoreBehindCmd(struct cmd_syndesc *as, void *arock)
        if (code) {
            Die(errno, ((allfiles == -1) ? 0 : "-allfiles"));
            error = 1;
+
+       } else if (blob.out_size == sizeof(tsb2)) {
+           async_default = tsb2.sb_default;
        }
     }
 
     /* Having no arguments also reports the default store asynchrony */
-    if (!error && verbose && (blob.out_size == sizeof(tsb2))) {
+    if (async_default >= 0 && verbose) {
        fprintf(stdout, "Default store asynchrony is %d kbytes.\n",
-               (tsb2.sb_default / 1024));
+               (async_default / 1024));
     }
 
     return error;
@@ -3790,8 +3826,8 @@ defect 3069
                          "list configured cells");
     cmd_AddParm(ts, "-numeric", CMD_FLAG, CMD_OPTIONAL, "addresses only");
 
-    ts = cmd_CreateSyntax("listaliases", ListAliasesCmd, NULL,
-                         "list configured cell aliases");
+    cmd_CreateSyntax("listaliases", ListAliasesCmd, NULL,
+                    "list configured cell aliases");
 
     ts = cmd_CreateSyntax("setquota", SetQuotaCmd, NULL, "set volume quota");
     cmd_AddParm(ts, "-path", CMD_SINGLE, CMD_OPTIONAL, "dir/file path");
@@ -3831,7 +3867,7 @@ defect 3069
     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, NULL, "list workstation's cell");
+    cmd_CreateSyntax("wscell", WSCellCmd, NULL, "list workstation's cell");
 
 /*
     ts = cmd_CreateSyntax("primarycell", PrimaryCellCmd, NULL, "obsolete (listed primary cell)");
@@ -3856,6 +3892,8 @@ defect 3069
                          "flush all data in volume");
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
 
+    cmd_CreateSyntax("flushall", FlushAllVolumesCmd, NULL, "flush all data from the cache");
+
     ts = cmd_CreateSyntax("sysname", SysNameCmd, NULL,
                          "get/set sysname (i.e. @sys) value");
     cmd_AddParm(ts, "-newsys", CMD_LIST, CMD_OPTIONAL, "new sysname");
@@ -3891,7 +3929,7 @@ defect 3069
                          "set cache manager encryption flag");
     cmd_AddParm(ts, "-crypt", CMD_SINGLE, 0, "on or off");
 
-    ts = cmd_CreateSyntax("getcrypt", GetCryptCmd, NULL,
+    cmd_CreateSyntax("getcrypt", GetCryptCmd, NULL,
                          "get cache manager encryption flag");
 
     ts = cmd_CreateSyntax("rxstatproc", RxStatProcCmd, NULL,
@@ -3972,6 +4010,9 @@ Die(int errnum, char *filename)
                    "%s: You do not have the required rights to do this operation\n",
                    pn);
        break;
+    case ESRCH: /* hack: pioctls stole ESRCH for cell name not available errors. */
+       fprintf(stderr, "%s: Cell name not recognized.\n", pn);
+       break;
     default:
        if (filename)
            fprintf(stderr, "%s:'%s'", pn, filename);
@@ -4124,7 +4165,6 @@ FlushMountCmd(struct cmd_syndesc *as, void *arock)
        code = pioctl(parent_dir, VIOC_AFS_FLUSHMOUNT, &blob, 1);
 
        free(last_component);
-       free(parent_dir);
 
        if (code != 0) {
            if (errno == EINVAL) {
@@ -4134,6 +4174,7 @@ FlushMountCmd(struct cmd_syndesc *as, void *arock)
            }
            error = 1;
        }
+       free(parent_dir);
     }
     return error;
 }