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;
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;
}
/* 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;
}
/* 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) {
/* 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);
}
/* 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);
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! */
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;
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;
}
}
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);
(*(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) \
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 */
};