support-nfs-translator-sysname-lists-20040317
authorDerrick Brashear <shadow@dementia.org>
Wed, 17 Mar 2004 06:43:34 +0000 (06:43 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 17 Mar 2004 06:43:34 +0000 (06:43 +0000)
support sysname lists in nfs translator

src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs_nfsclnt.c
src/afs/afs_pioctl.c
src/afs/afs_prototypes.h
src/afs/exporter.h
src/afs/nfsclient.h

index f377ea6..f1581ca 100644 (file)
@@ -400,40 +400,49 @@ afs_ENameOK(register char *aname)
     return 1;
 }
 
-int
+static int
 afs_getsysname(register struct vrequest *areq, register struct vcache *adp,
-              register char *bufp)
+               register char *bufp, int *num, char **sysnamelist[])
 {
     register struct unixuser *au;
     register afs_int32 error;
 
-    if (!afs_nfsexporter) {
-       strcpy(bufp, afs_sysname);
-       return 0;
-    }
     AFS_STATCNT(getsysname);
-    au = afs_GetUser(areq->uid, adp->fid.Cell, 0);
-    afs_PutUser(au, 0);
-    if (au->exporter) {
-       error = EXP_SYSNAME(au->exporter, NULL, bufp);
-       if (error)
-           strcpy(bufp, "@sys");
-       return -1;
-    } else {
-       strcpy(bufp, afs_sysname);
-       return 0;
+
+    *sysnamelist = afs_sysnamelist;
+
+    if (!afs_nfsexporter) 
+       strcpy(bufp, (*sysnamelist)[0]);
+    else {
+       au = afs_GetUser(areq->uid, adp->fid.Cell, 0);
+       if (au->exporter) {
+           error = EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, num);
+           if (error) {
+               strcpy(bufp, "@sys");
+               afs_PutUser(au, 0);   
+               return -1;
+           } else {
+               strcpy(bufp, (*sysnamelist)[0]);
+           }
+       } else 
+           strcpy(bufp, afs_sysname);
+       afs_PutUser(au, 0);       
     }
+    return 0;
 }
 
 void
-Check_AtSys(register struct vcache *avc, const char *aname,
-           struct sysname_info *state, struct vrequest *areq)
+Check_AtSys(register struct vcache *avc, char *aname, 
+            struct sysname_info *state, struct vrequest *areq)
 {
+    int num = 0;
+    char **sysnamelist[MAXSYSNAME];
+
     if (AFS_EQ_ATSYS(aname)) {
        state->offset = 0;
        state->name = (char *)osi_AllocLargeSpace(AFS_SMALLOCSIZ);
        state->allocked = 1;
-       state->index = afs_getsysname(areq, avc, state->name);
+       state->index = afs_getsysname(areq, avc, state->name, &num, sysnamelist);
     } else {
        state->offset = -1;
        state->allocked = 0;
@@ -444,32 +453,54 @@ Check_AtSys(register struct vcache *avc, const char *aname,
 
 int
 Next_AtSys(register struct vcache *avc, struct vrequest *areq,
-          struct sysname_info *state)
+           struct sysname_info *state)
 {
+    int num = afs_sysnamecount;
+    char **sysnamelist[MAXSYSNAME];
+
     if (state->index == -1)
-       return 0;               /* No list */
+       return 0;       /* No list */
 
-    /* Check for the initial state of aname != "@sys" in Check_AtSys */
+    /* Check for the initial state of aname != "@sys" in Check_AtSys*/
     if (state->offset == -1 && state->allocked == 0) {
-       register char *tname;
-       /* Check for .*@sys */
-       for (tname = state->name; *tname; tname++)
-           /*Move to the end of the string */ ;
-       if ((tname > state->name + 4) && (AFS_EQ_ATSYS(tname - 4))) {
-           state->offset = (tname - 4) - state->name;
-           tname = (char *)osi_AllocLargeSpace(AFS_LRALLOCSIZ);
-           strncpy(tname, state->name, state->offset);
-           state->name = tname;
-           state->allocked = 1;
-           state->index =
-               afs_getsysname(areq, avc, state->name + state->offset);
-           return 1;
-       } else
-           return 0;           /* .*@sys doesn't match either */
-    } else if (++(state->index) >= afs_sysnamecount
-              || !afs_sysnamelist[(int)state->index])
-       return 0;               /* end of list */
-    strcpy(state->name + state->offset, afs_sysnamelist[(int)state->index]);
+       register char *tname;
+
+       /* Check for .*@sys */
+       for (tname=state->name; *tname; tname++)
+           /*Move to the end of the string*/;
+
+       if ((tname > state->name + 4) && (AFS_EQ_ATSYS(tname-4))) {
+           state->offset = (tname - 4) - state->name;
+           tname = (char *) osi_AllocLargeSpace(AFS_LRALLOCSIZ);
+           strncpy(tname, state->name, state->offset);
+           state->name = tname;
+           state->allocked = 1;
+            num = 0;
+            state->index = afs_getsysname(areq, avc, state->name+state->offset,
+                                          &num, sysnamelist);
+           return 1;
+       } else
+           return 0; /* .*@sys doesn't match either */
+    } else {
+       register struct unixuser *au;
+       register afs_int32 error;
+      
+       *sysnamelist = afs_sysnamelist;
+
+       if (afs_nfsexporter) {
+           au = afs_GetUser(areq->uid, avc->fid.Cell, 0);
+           if (au->exporter) {
+               error = EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, num);
+               if (error) {
+                   return 0;
+               }
+           } 
+           afs_PutUser(au, 0); 
+       }
+       if (++(state->index) >= num || !(*sysnamelist)[state->index])
+           return 0;   /* end of list */
+    }
+    strcpy(state->name+state->offset, (*sysnamelist)[state->index]);
     return 1;
 }
 
index c970f0f..b433dd2 100644 (file)
@@ -298,24 +298,37 @@ afs_nfsclient_hold(np)
 
 
 /* if inname is non-null, a new system name value is set for the remote user (inname contains the new sysname). In all cases, outname returns the current sysname value for this remote user */
-int
-afs_nfsclient_sysname(np, inname, outname)
-     register struct nfsclientpag *np;
-     char *inname, *outname;
+int 
+afs_nfsclient_sysname(register struct nfsclientpag *np, char *inname, 
+                     char **outname[], int *num)
 {
+    char *cp;
+    int count, t;
 #if defined(AFS_SGIMP_ENV)
     osi_Assert(ISAFS_GLOCK());
 #endif
     AFS_STATCNT(afs_nfsclient_sysname);
     if (inname) {
-       if (!np->sysname) {
-           np->sysname = afs_osi_Alloc(MAXSYSNAME);
+       if (np->sysname) {
+           for(count=0; count < np->sysnamecount;++count) {
+               afs_osi_Free(np->sysname[count], MAXSYSNAME);
+           }
+       }
+       for(count=0; count < *num;++count) {
+           np->sysname[count]= afs_osi_Alloc(MAXSYSNAME);
+       }
+       cp = inname;
+       for(count=0; count < *num;++count) {
+           t = strlen(cp);
+           memcpy(np->sysname[count], cp, t+1); /* include null */
+           cp += t+1;
        }
-       strcpy(np->sysname, inname);
+       np->sysnamecount = *num;
     } else if (!np->sysname) {
-       return ENODEV;          /* XXX */
+       return ENODEV;      /* XXX */
     }
-    strcpy(outname, np->sysname);
+    *outname = np->sysname;
+    *num = np->sysnamecount;
     return 0;
 }
 
index 05f5100..f4e77c0 100644 (file)
@@ -2643,13 +2643,13 @@ DECL_PIOCTL(PGetVnodeXStatus)
  /* for the reader.  */
 DECL_PIOCTL(PSetSysName)
 {
-    char *cp, inname[MAXSYSNAME], outname[MAXSYSNAME];
+    char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME];
     int setsysname, foundname = 0;
     register struct afs_exporter *exporter;
     register struct unixuser *au;
     register afs_int32 pag, error;
-    int t, count;
-
+    int t, count, num = 0;
+    char **sysnamelist[MAXSYSNAME];
 
     AFS_STATCNT(PSetSysName);
     if (!afs_globalVFS) {
@@ -2668,6 +2668,7 @@ DECL_PIOCTL(PSetSysName)
        /* Check my args */
        if (setsysname < 0 || setsysname > MAXNUMSYSNAMES)
            return EINVAL;
+       cp2 = ain;
        for (cp = ain, count = 0; count < setsysname; count++) {
            /* won't go past end of ain since maxsysname*num < ain length */
            t = strlen(cp);
@@ -2680,10 +2681,11 @@ DECL_PIOCTL(PSetSysName)
        }
        /* args ok */
 
-       /* inname gets first entry in case we're being a translater */
+       /* inname gets first entry in case we're being a translator */
        t = strlen(ain);
        memcpy(inname, ain, t + 1);     /* include terminating null */
        ain += t + 1;
+       num = count;
     }
     if ((*acred)->cr_gid == RMTUSER_REQ) {     /* Handles all exporters */
        pag = PagInCred(*acred);
@@ -2697,7 +2699,8 @@ DECL_PIOCTL(PSetSysName)
            afs_PutUser(au, READ_LOCK);
            return EINVAL;      /* Better than panicing */
        }
-       error = EXP_SYSNAME(exporter, (setsysname ? inname : NULL), outname);
+       error = EXP_SYSNAME(exporter, (setsysname ? cp2 : NULL), sysnamelist,
+                           &num);
        if (error) {
            if (error == ENODEV)
                foundname = 0;  /* sysname not set yet! */
@@ -2705,17 +2708,19 @@ DECL_PIOCTL(PSetSysName)
                afs_PutUser(au, READ_LOCK);
                return error;
            }
-       } else
-           foundname = 1;
+       } else {
+            foundname = num;
+            strcpy(outname, (*sysnamelist)[0]);
+       }
        afs_PutUser(au, READ_LOCK);
     } else {
-
        /* Not xlating, so local case */
        if (!afs_sysname)
            osi_Panic("PSetSysName: !afs_sysname\n");
        if (!setsysname) {      /* user just wants the info */
            strcpy(outname, afs_sysname);
            foundname = afs_sysnamecount;
+           *sysnamelist = afs_sysnamelist;
        } else {                /* Local guy; only root can change sysname */
            if (!afs_osi_suser(*acred))
                return EACCES;
@@ -2746,14 +2751,13 @@ DECL_PIOCTL(PSetSysName)
            strcpy(cp, outname);        /* ... the entry, ... */
            cp += strlen(outname) + 1;
            for (count = 1; count < foundname; ++count) {       /* ... or list. */
-               /* Note: we don't support @sys lists for exporters */
-               if (!afs_sysnamelist[count])
+               if (!(*sysnamelist)[count])
                    osi_Panic
                        ("PSetSysName: no afs_sysnamelist entry to read\n");
-               t = strlen(afs_sysnamelist[count]);
+               t = strlen((*sysnamelist)[count]);
                if (t >= MAXSYSNAME)
                    osi_Panic("PSetSysName: sysname entry garbled\n");
-               strcpy(cp, afs_sysnamelist[count]);
+               strcpy(cp, (*sysnamelist)[count]);
                cp += t + 1;
            }
        }
index 07ae65a..adaf96f 100644 (file)
@@ -950,9 +950,7 @@ extern int afs_TryEvalFakeStat(struct vcache **avcp,
                               struct vrequest *areq);
 extern void afs_PutFakeStat(struct afs_fakestat_state *state);
 extern int afs_ENameOK(register char *aname);
-extern int afs_getsysname(register struct vrequest *areq,
-                         register struct vcache *adp, register char *bufp);
-extern void Check_AtSys(register struct vcache *avc, const char *aname,
+extern void Check_AtSys(register struct vcache *avc, char *aname,
                        struct sysname_info *state, struct vrequest *areq);
 extern int Next_AtSys(register struct vcache *avc, struct vrequest *areq,
                      struct sysname_info *state);
index 79409c8..61371b4 100644 (file)
@@ -93,8 +93,8 @@ struct afs_exporter {
         (*(EXP)->exp_op->export_hold)(EXP)
 #define        EXP_RELE(EXP)   \
         (*(EXP)->exp_op->export_rele)(EXP)
-#define        EXP_SYSNAME(EXP, INNAME, OUTNAME)   \
-        (*(EXP)->exp_op->export_sysname)(EXP, INNAME, OUTNAME)
+#define        EXP_SYSNAME(EXP, INNAME, OUTNAME, NUM)   \
+        (*(EXP)->exp_op->export_sysname)(EXP, INNAME, OUTNAME, NUM)
 #define        EXP_GC(EXP, param)      \
         (*(EXP)->exp_op->export_garbagecollect)(EXP, param)
 #define        EXP_STATISTICS(EXP)     \
index 9d7df83..0db9d3c 100644 (file)
@@ -28,7 +28,8 @@ struct nfsclientpag {
     afs_int32 uid;             /* search based on uid and ... */
     afs_int32 host;            /* ... nfs client's host ip address */
     afs_int32 pag;             /* active pag for all  (uid, host) "unpaged" conns */
-    char *sysname;             /* user's "@sys" value; also kept in unixuser */
+    char *sysname[MAXNUMSYSNAMES];/* user's "@sys" value; also kept in unixuser */
+    int sysnamecount;           /*  number of sysnames */
     afs_int32 lastcall;                /*  Used for timing out nfsclientpag structs  */
 };