blob: 4ef426d9d84fa42a11183eb2138893f220387e04 [file] [log] [blame]
/* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
/* See COPYRIGHT */
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <9pclient.h>
#include "fsimpl.h"
CFid*
fswalk(CFid *fid, char *oname)
{
char *freep, *name;
int i, nwalk;
char *p;
CFid *wfid;
Fcall tx, rx;
freep = nil;
name = oname;
if(name){
freep = malloc(strlen(name)+1);
if(freep == nil)
return nil;
strcpy(freep, name);
name = freep;
}
if((wfid = _fsgetfid(fid->fs)) == nil){
free(freep);
return nil;
}
nwalk = 0;
do{
/* collect names */
for(i=0; name && *name && i < MAXWELEM; ){
p = name;
name = strchr(name, '/');
if(name)
*name++ = 0;
if(*p == 0 || (*p == '.' && *(p+1) == 0))
continue;
tx.wname[i++] = p;
}
/* do a walk */
tx.type = Twalk;
tx.fid = nwalk ? wfid->fid : fid->fid;
tx.newfid = wfid->fid;
tx.nwname = i;
if(_fsrpc(fid->fs, &tx, &rx, 0) < 0){
Error:
free(freep);
if(nwalk)
fsclose(wfid);
else
_fsputfid(wfid);
return nil;
}
if(rx.nwqid != tx.nwname){
/* XXX lame error */
werrstr("file '%s' not found", oname);
goto Error;
}
if(rx.nwqid == 0)
wfid->qid = fid->qid;
else
wfid->qid = rx.wqid[rx.nwqid-1];
nwalk++;
}while(name && *name);
return wfid;
}