| /* 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; | 
 | } |