ref: 9731b2c5e105e92d14a7899fddd7142f6f99fc3f
parent: 39347ab47dab6c556bb37ced7526bfcc8de4cf9b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Feb 25 03:31:01 EST 2016
fix devfs-*.c to not use cname hack to get file path, get rid of MAXPATH limit, make root accessible under /mnt/term/root under linux, it was not possible to access the clients /mnt directory as it gets hidden by #/mnt, to solve this, we first bind #U to /root, and then let cpumain() bind any subdirectory (-r option) in there and finally bind /root after /. for this to work, i had to get rid of the dreadfull cname hack, where the c->name is used to derive the unix file path. this did not work when the device was accessed form a different bind... and it also leaked memory in cclone() as the c->name's where doubly maintained in fswalk(). also get rid of the fixed MAXPATH sized stack buffers. each devfs now maintains a dynamic buffer in ther Ufsinfo structure. under windows, this is a wide string. remove the #ifdef UNICODE maze from devfs-posix.c, we always assume unicode now with wide strings.
--- a/cpu.c
+++ b/cpu.c
@@ -29,7 +29,6 @@
static char *system;
static int cflag;
extern int dbg;
-extern char* base; // fs base for devroot
static char *srvname = "ncpu";
static char *ealgs = "rc4_256 sha1";
@@ -69,7 +68,7 @@
void
usage(void)
{
- fprint(2, "usage: drawterm [-a authserver] [-c cpuserver] [-s secstore] [-u user]\n");
+ fprint(2, "usage: drawterm [-a authserver] [-c cpuserver] [-s secstore] [-u user] [-r root]\n");
exits("usage");
}
int fdd;
@@ -168,6 +167,12 @@
if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
ealgs = nil;
break;
+ case 'r':
+ snprint(buf, sizeof(buf), "/root/%s", EARGF(usage()));
+ cleanname(buf);
+ if(bind(buf, "/root", MREPL) < 0)
+ panic("bind /root: %r");
+ break;
case 'C':
cflag++;
cmd[0] = '!';
@@ -180,9 +185,6 @@
case 'k':
keyspec = EARGF(usage());
break;
- case 'r':
- base = EARGF(usage());
- break;
case 's':
secstoreserver = EARGF(usage());
break;
@@ -195,6 +197,9 @@
if(argc != 0)
usage();
+
+ if(bind("/root", "/", MAFTER) < 0)
+ panic("bind /root: %r");
if(system == nil)
system = readcons("cpu", "cpu", 0);
--- a/kern/devfs-posix.c
+++ b/kern/devfs-posix.c
@@ -15,17 +15,7 @@
#include "fns.h"
#include "error.h"
-
typedef struct Ufsinfo Ufsinfo;
-
-enum
-{
- NUID = 256,
- NGID = 256,
- MAXPATH = 1024,
- MAXCOMP = 128
-};
-
struct Ufsinfo
{
int mode;
@@ -35,36 +25,20 @@
DIR* dir;
vlong offset;
QLock oq;
+ char* path;
char nextname[NAME_MAX];
};
-char *base = "/";
-
static Qid fsqid(struct stat *);
-static void fspath(Chan*, char*, char*);
+static char* catpath(char*, char*);
static ulong fsdirread(Chan*, uchar*, int, ulong);
static int fsomode(int);
-/* clumsy hack, but not worse than the Path stuff in the last one */
static char*
-uc2name(Chan *c)
+lastelem(char *s)
{
- char *s;
+ char *t;
- if(c->name == nil)
- return "/";
- s = c2name(c);
- if(s[0]=='#' && s[1]=='U')
- return s+2;
- return s;
-}
-
-static char*
-lastelem(Chan *c)
-{
- char *s, *t;
-
- s = uc2name(c);
if((t = strrchr(s, '/')) == nil)
return s;
if(t[1] == 0)
@@ -80,9 +54,6 @@
static int devno;
Ufsinfo *uif;
- if(stat(base, &stbuf) < 0)
- error(strerror(errno));
-
c = devattach('U', spec);
uif = mallocz(sizeof(Ufsinfo), 1);
@@ -89,6 +60,7 @@
uif->mode = stbuf.st_mode;
uif->uid = stbuf.st_uid;
uif->gid = stbuf.st_gid;
+ uif->path = strdup("/");
c->aux = uif;
c->dev = devno++;
@@ -105,6 +77,7 @@
uif = mallocz(sizeof(Ufsinfo), 1);
*uif = *(Ufsinfo*)c->aux;
+ uif->path = strdup(uif->path);
nc->aux = uif;
return nc;
@@ -114,18 +87,20 @@
fswalk1(Chan *c, char *name)
{
struct stat stbuf;
- char path[MAXPATH];
Ufsinfo *uif;
+ char *path;
- fspath(c, name, path);
-
/*print("** fs walk '%s' -> %s\n", path, name); */
- if(stat(path, &stbuf) < 0)
+ uif = c->aux;
+ path = catpath(uif->path, name);
+ if(stat(path, &stbuf) < 0){
+ free(path);
return 0;
+ }
+ free(uif->path);
+ uif->path = path;
- uif = c->aux;
-
uif->mode = stbuf.st_mode;
uif->uid = stbuf.st_uid;
uif->gid = stbuf.st_gid;
@@ -135,13 +110,10 @@
return 1;
}
-extern Cname* addelem(Cname*, char*);
-
static Walkqid*
fswalk(Chan *c, Chan *nc, char **name, int nname)
{
int i;
- Cname *cname;
Walkqid *wq;
if(nc != nil)
@@ -148,19 +120,13 @@
panic("fswalk: nc != nil");
wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
nc = devclone(c);
- cname = c->name;
- incref(&cname->ref);
-
fsclone(c, nc);
wq->clone = nc;
for(i=0; i<nname; i++){
- nc->name = cname;
if(fswalk1(nc, name[i]) == 0)
break;
- cname = addelem(cname, name[i]);
wq->qid[i] = nc->qid;
}
- nc->name = cname;
if(i != nname){
cclose(nc);
wq->clone = nil;
@@ -174,19 +140,19 @@
{
Dir d;
struct stat stbuf;
- char path[MAXPATH];
+ Ufsinfo *uif;
if(n < BIT16SZ)
error(Eshortstat);
- fspath(c, 0, path);
- if(stat(path, &stbuf) < 0)
+ uif = c->aux;
+ if(stat(uif->path, &stbuf) < 0)
error(strerror(errno));
- d.name = lastelem(c);
- d.uid = "unknown";
- d.gid = "unknown";
- d.muid = "unknown";
+ d.name = lastelem(uif->path);
+ d.uid = eve;
+ d.gid = eve;
+ d.muid = eve;
d.qid = c->qid;
d.mode = (c->qid.type<<24)|(stbuf.st_mode&0777);
d.atime = stbuf.st_atime;
@@ -200,7 +166,6 @@
static Chan*
fsopen(Chan *c, int mode)
{
- char path[MAXPATH];
int m, isdir;
Ufsinfo *uif;
@@ -231,10 +196,8 @@
c->mode = openmode(mode);
uif = c->aux;
-
- fspath(c, 0, path);
if(isdir) {
- uif->dir = opendir(path);
+ uif->dir = opendir(uif->path);
if(uif->dir == 0)
error(strerror(errno));
}
@@ -241,8 +204,7 @@
else {
if(mode & OTRUNC)
m |= O_TRUNC;
- uif->fd = open(path, m, 0666);
-
+ uif->fd = open(uif->path, m, 0666);
if(uif->fd < 0)
error(strerror(errno));
}
@@ -257,16 +219,18 @@
fscreate(Chan *c, char *name, int mode, ulong perm)
{
int fd, m;
- char path[MAXPATH];
+ char *path;
struct stat stbuf;
Ufsinfo *uif;
m = fsomode(mode&3);
- fspath(c, name, path);
-
uif = c->aux;
-
+ path = catpath(uif->path, name);
+ if(waserror()){
+ free(path);
+ nexterror();
+ }
if(perm & DMDIR) {
if(m)
error(Eperm);
@@ -299,9 +263,13 @@
error(strerror(errno));
uif->fd = fd;
}
-
if(stat(path, &stbuf) < 0)
error(strerror(errno));
+
+ free(uif->path);
+ uif->path = path;
+ poperror();
+
c->qid = fsqid(&stbuf);
c->offset = 0;
c->flag |= COPEN;
@@ -314,7 +282,6 @@
Ufsinfo *uif;
uif = c->aux;
-
if(c->flag & COPEN) {
if(c->qid.type & QTDIR)
closedir(uif->dir);
@@ -321,7 +288,7 @@
else
close(uif->fd);
}
-
+ free(uif->path);
free(uif);
}
@@ -367,7 +334,6 @@
Ufsinfo *uif;
uif = c->aux;
-
qlock(&uif->oq);
if(waserror()) {
qunlock(&uif->oq);
@@ -396,13 +362,13 @@
fsremove(Chan *c)
{
int n;
- char path[MAXPATH];
+ Ufsinfo *uif;
- fspath(c, 0, path);
+ uif = c->aux;
if(c->qid.type & QTDIR)
- n = rmdir(path);
+ n = rmdir(uif->path);
else
- n = remove(path);
+ n = remove(uif->path);
if(n < 0)
error(strerror(errno));
}
@@ -412,34 +378,39 @@
{
Dir d;
struct stat stbuf;
- char old[MAXPATH], new[MAXPATH];
- char strs[MAXPATH*3], *p;
+ char strs[NAME_MAX*3];
Ufsinfo *uif;
if(convM2D(buf, n, &d, strs) != n)
error(Ebadstat);
- fspath(c, 0, old);
- if(stat(old, &stbuf) < 0)
+ uif = c->aux;
+ if(stat(uif->path, &stbuf) < 0)
error(strerror(errno));
- uif = c->aux;
-
- fspath(c, 0, old);
if(~d.mode != 0 && (int)(d.mode&0777) != (int)(stbuf.st_mode&0777)) {
- if(chmod(old, d.mode&0777) < 0)
+ if(chmod(uif->path, d.mode&0777) < 0)
error(strerror(errno));
uif->mode &= ~0777;
uif->mode |= d.mode&0777;
}
- if(d.name[0] && strcmp(d.name, lastelem(c)) != 0) {
- fspath(c, 0, old);
- strcpy(new, old);
- p = strrchr(new, '/');
- strcpy(p+1, d.name);
- if(rename(old, new) < 0)
+ if(d.name[0] && strcmp(d.name, lastelem(uif->path)) != 0) {
+ char *base, *newpath;
+
+ base = strdup(uif->path);
+ if(waserror()){
+ free(base);
+ nexterror();
+ }
+ *lastelem(base) = 0;
+ newpath = catpath(base, d.name);
+ free(base), base = newpath;
+ if(rename(uif->path, newpath) < 0)
error(strerror(errno));
+ free(uif->path);
+ uif->path = newpath;
+ poperror();
}
/*
@@ -472,17 +443,20 @@
return q;
}
-static void
-fspath(Chan *c, char *ext, char *path)
+static char*
+catpath(char *base, char *ext)
{
- strcpy(path, base);
- strcat(path, "/");
- strcat(path, uc2name(c));
- if(ext){
- strcat(path, "/");
- strcat(path, ext);
- }
- cleanname(path);
+ char *path;
+ int n, m;
+
+ n = strlen(base);
+ m = strlen(ext);
+ path = malloc(n+m+2);
+ memmove(path, base, n);
+ if(n > 0 && path[n-1] != '/')
+ path[n++] = '/';
+ memmove(path+n, ext, m+1);
+ return path;
}
static int
@@ -526,7 +500,6 @@
long n;
char de[NAME_MAX];
struct stat stbuf;
- char path[MAXPATH], dirpath[MAXPATH];
Ufsinfo *uif;
/*print("fsdirread %s\n", c2name(c));*/
@@ -542,9 +515,9 @@
rewinddir(uif->dir);
}
- fspath(c, 0, dirpath);
-
while(i+BIT16SZ < count) {
+ char *p;
+
if(!p9readdir(de, uif))
break;
@@ -552,17 +525,17 @@
continue;
d.name = de;
- sprint(path, "%s/%s", dirpath, de);
- memset(&stbuf, 0, sizeof stbuf);
-
- if(stat(path, &stbuf) < 0) {
+ p = catpath(uif->path, de);
+ if(stat(p, &stbuf) < 0) {
/* fprint(2, "dir: bad path %s\n", path); */
/* but continue... probably a bad symlink */
+ memset(&stbuf, 0, sizeof stbuf);
}
+ free(p);
- d.uid = "unknown";
- d.gid = "unknown";
- d.muid = "unknown";
+ d.uid = eve;
+ d.gid = eve;
+ d.muid = eve;
d.qid = fsqid(&stbuf);
d.mode = (d.qid.type<<24)|(stbuf.st_mode&0777);
d.atime = stbuf.st_atime;
--- a/kern/devfs-win32.c
+++ b/kern/devfs-win32.c
@@ -14,10 +14,8 @@
typedef struct DIR DIR;
typedef struct Ufsinfo Ufsinfo;
-
enum
{
- MAXPATH = 1024,
TPATH_ROOT = 0, // ""
TPATH_VOLUME = 1, // "C:"
TPATH_FILE = 2, // "C:\bla"
@@ -30,8 +28,8 @@
WIN32_FIND_DATA wfd;
// for GetLogicalDriveStrings()
- TCHAR *drivebuf;
- TCHAR *drivep;
+ wchar_t *drivebuf;
+ wchar_t *drivep;
// dont move to the next item
int keep;
@@ -44,17 +42,16 @@
DIR* dir;
vlong offset;
QLock oq;
+ wchar_t *path;
};
-static void fspath(Chan *, char *, TCHAR *, int);
+static wchar_t *catpath(wchar_t *, char *, wchar_t *);
static ulong fsdirread(Chan*, uchar*, int, vlong);
static int fsomode(int);
static ulong fsaccess(int);
-static ulong pathtype(TCHAR *);
-static int checkvolume(TCHAR *);
+static ulong pathtype(wchar_t *);
+static int checkvolume(wchar_t *);
-char *base = "";
-
static ulong
unixtime(FILETIME *ft)
{
@@ -65,12 +62,10 @@
}
static uvlong
-pathhash(TCHAR *p)
+pathhash(wchar_t *p)
{
uchar digest[SHA1dlen];
- int n;
- for(n=0; p[n] != 0; n++);
- sha1((uchar*)p, n*sizeof(TCHAR), digest, nil);
+ sha1((uchar*)p, wcslen(p)*sizeof(wchar_t), digest, nil);
return *(uvlong*)digest;
}
@@ -89,7 +84,7 @@
}
static Qid
-wfdtoqid(TCHAR *path, WIN32_FIND_DATA *wfd)
+wfdtoqid(wchar_t *path, WIN32_FIND_DATA *wfd)
{
ulong t;
WIN32_FIND_DATA f;
@@ -96,7 +91,6 @@
Qid q;
t = pathtype(path);
-
switch(t){
case TPATH_VOLUME:
case TPATH_ROOT:
@@ -122,14 +116,10 @@
}
static void
-wfdtodir(TCHAR *path, Dir *d, WIN32_FIND_DATA *wfd)
+wfdtodir(wchar_t *path, Dir *d, WIN32_FIND_DATA *wfd)
{
WIN32_FIND_DATA f;
- d->uid = "nul";
- d->gid = "nul";
- d->muid = "nul";
-
switch(pathtype(path)){
case TPATH_VOLUME:
case TPATH_ROOT:
@@ -141,7 +131,7 @@
break;
case TPATH_FILE:
- if(!wfd){
+ if(wfd == nil){
HANDLE h;
if((h = FindFirstFile(path, &f))==INVALID_HANDLE_VALUE)
oserror();
@@ -155,30 +145,17 @@
break;
}
d->qid = wfdtoqid(path, wfd);
+ d->uid = eve;
+ d->gid = eve;
+ d->muid = eve;
}
-/* clumsy hack, but not worse than the Path stuff in the last one */
static char*
-uc2name(Chan *c)
-{
- char *s;
-
- if(c->name == nil)
- return "";
- s = c2name(c);
- if(s[0]=='#' && s[1]=='U')
- s += 2;
- if(*s=='/')
- s++;
- return s;
-}
-
-static char*
lastelem(Chan *c)
{
char *s, *t;
- s = uc2name(c);
+ s = c2name(c);
if((t = strrchr(s, '/')) == nil)
return s;
if(t[1] == 0)
@@ -187,35 +164,26 @@
}
static ulong
-pathtype(TCHAR *path)
+pathtype(wchar_t *path)
{
- int n;
- n = wcslen(path);
- if(n < 2){
+ if(path[0] == 0 || path[1] == 0)
return TPATH_ROOT;
- }
- if(n==2){
+ if(path[1] == ':' && path[2] == 0)
return TPATH_VOLUME;
- }
return TPATH_FILE;
}
static int
-checkvolume(TCHAR *path)
+checkvolume(wchar_t *path)
{
- TCHAR vol[MAX_PATH];
- TCHAR volname[MAX_PATH];
- TCHAR fsysname[MAX_PATH];
+ wchar_t vol[MAX_PATH];
+ wchar_t volname[MAX_PATH];
+ wchar_t fsysname[MAX_PATH];
DWORD complen;
DWORD flags;
- wcsncpy(vol, path, MAX_PATH);
-#ifdef UNICODE
- wcsncat(vol, L"\\", MAXPATH);
-#else
- wcsncat(vol, "\\", MAXPATH);
-#endif
-
+ wcscpy(vol, path);
+ wcscat(vol, L"\\");
if(!GetVolumeInformation(
vol,
volname,
@@ -224,27 +192,35 @@
&complen,
&flags,
fsysname,
- MAX_PATH)){
+ MAX_PATH))
return 0;
- }
+
return 1;
}
-static int
-getfileowner(TCHAR *path, char *owner, int nowner)
+static wchar_t*
+wstrdup(wchar_t *s)
{
- strncpy(owner, "Bill", nowner);
- return 1;
+ wchar_t *d;
+ long n;
+
+ n = (wcslen(s)+1)*sizeof(wchar_t);
+ d = mallocz(n, 0);
+ memmove(d, s, n);
+ return d;
}
static Chan*
fsattach(char *spec)
{
- Chan *c;
static int devno;
Ufsinfo *uif;
- c = devattach('U', spec);
+ Chan *c;
+
uif = mallocz(sizeof(Ufsinfo), 1);
+ uif->path = wstrdup(L"");
+
+ c = devattach('U', spec);
c->aux = uif;
c->dev = devno++;
c->qid.type = QTDIR;
@@ -259,6 +235,7 @@
uif = mallocz(sizeof(Ufsinfo), 1);
*uif = *(Ufsinfo*)c->aux;
+ uif->path = wstrdup(uif->path);
nc->aux = uif;
return nc;
@@ -267,37 +244,41 @@
static int
fswalk1(Chan *c, char *name)
{
- HANDLE h;
WIN32_FIND_DATA wfd;
- TCHAR path[MAXPATH];
-
- fspath(c, name, path, MAXPATH);
-
- switch(pathtype(path)){
+ HANDLE h;
+ wchar_t *p;
+ Ufsinfo *uif;
+
+ uif = c->aux;
+ p = catpath(uif->path, name, nil);
+ switch(pathtype(p)){
case TPATH_VOLUME:
- if(!checkvolume(path))
+ if(!checkvolume(p)){
+ free(p);
return 0;
+ }
case TPATH_ROOT:
- c->qid = wfdtoqid(path, nil);
+ c->qid = wfdtoqid(p, nil);
break;
case TPATH_FILE:
- if((h = FindFirstFile(path, &wfd)) == INVALID_HANDLE_VALUE)
+ if((h = FindFirstFile(p, &wfd)) == INVALID_HANDLE_VALUE){
+ free(p);
return 0;
+ }
FindClose(h);
- c->qid = wfdtoqid(path, &wfd);
+ c->qid = wfdtoqid(p, &wfd);
break;
}
+ free(uif->path);
+ uif->path = p;
return 1;
}
-extern Cname* addelem(Cname*, char*);
-
static Walkqid*
fswalk(Chan *c, Chan *nc, char **name, int nname)
{
int i;
- Cname *cname;
Walkqid *wq;
if(nc != nil)
@@ -304,19 +285,13 @@
panic("fswalk: nc != nil");
wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
nc = devclone(c);
- cname = c->name;
- incref(&cname->ref);
-
fsclone(c, nc);
wq->clone = nc;
for(i=0; i<nname; i++){
- nc->name = cname;
if(fswalk1(nc, name[i]) == 0)
break;
- cname = addelem(cname, name[i]);
wq->qid[i] = nc->qid;
}
- nc->name = cname;
if(i != nname){
cclose(nc);
wq->clone = nil;
@@ -329,21 +304,13 @@
fsstat(Chan *c, uchar *buf, int n)
{
Dir d;
- TCHAR path[MAXPATH];
- char owner[MAXPATH];
+ Ufsinfo *uif;
if(n < BIT16SZ)
error(Eshortstat);
- fspath(c, 0, path, MAXPATH);
+ uif = c->aux;
d.name = lastelem(c);
- wfdtodir(path, &d, nil);
-
- if(getfileowner(path, owner, MAXPATH)){
- d.uid = owner;
- d.gid = owner;
- d.muid = owner;
- }
-
+ wfdtodir(uif->path, &d, nil);
d.type = 'U';
d.dev = c->dev;
return convD2M(&d, buf, n);
@@ -352,9 +319,9 @@
static Chan*
fsopen(Chan *c, int mode)
{
- TCHAR path[MAXPATH];
ulong t;
int m, isdir;
+ wchar_t *p;
Ufsinfo *uif;
m = mode & (OTRUNC|3);
@@ -381,14 +348,13 @@
c->mode = openmode(mode);
uif = c->aux;
uif->offset = 0;
- fspath(c, 0, path, MAXPATH);
- t = pathtype(path);
+ t = pathtype(uif->path);
if(isdir){
DIR *d;
d = malloc(sizeof(*d));
switch(t){
case TPATH_ROOT:
- d->drivebuf = malloc(sizeof(TCHAR)*MAX_PATH);
+ d->drivebuf = malloc(sizeof(wchar_t)*MAX_PATH);
if(GetLogicalDriveStrings(MAX_PATH-1, d->drivebuf) == 0){
free(d->drivebuf);
d->drivebuf = nil;
@@ -398,12 +364,10 @@
break;
case TPATH_VOLUME:
case TPATH_FILE:
-#ifdef UNICODE
- wcsncat(path, L"\\*.*", MAXPATH);
-#else
- wcsncat(path, "\\*.*", MAXPATH);
-#endif
- if((d->handle = FindFirstFile(path, &d->wfd)) == INVALID_HANDLE_VALUE){
+ p = catpath(uif->path, "*.*", nil);
+ d->handle = FindFirstFile(p, &d->wfd);
+ free(p);
+ if(d->handle == INVALID_HANDLE_VALUE){
free(d);
oserror();
}
@@ -414,15 +378,14 @@
} else {
uif->dir = nil;
if((uif->fh = CreateFile(
- path,
+ uif->path,
fsaccess(mode),
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
(mode & OTRUNC) ? TRUNCATE_EXISTING : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
- 0)) == INVALID_HANDLE_VALUE){
+ 0)) == INVALID_HANDLE_VALUE)
oserror();
- }
}
c->offset = 0;
c->flag |= COPEN;
@@ -433,52 +396,51 @@
fscreate(Chan *c, char *name, int mode, ulong perm)
{
int m;
- TCHAR path[MAXPATH];
- Ufsinfo *uif;
ulong t;
+ wchar_t *newpath;
+ Ufsinfo *uif;
m = fsomode(mode&3);
-
- fspath(c, name, path, MAXPATH);
- t = pathtype(path);
-
uif = c->aux;
-
+ t = pathtype(uif->path);
+ newpath = catpath(uif->path, name, nil);
+ if(waserror()){
+ free(newpath);
+ nexterror();
+ }
if(perm & DMDIR) {
- TCHAR *p;
+ wchar_t *p;
DIR *d;
if(m || t!=TPATH_FILE)
error(Eperm);
- if(!CreateDirectory(path, NULL))
+ if(!CreateDirectory(newpath, NULL))
oserror();
d = malloc(sizeof(*d));
- p = &path[wcslen(path)];
-#ifdef UNICODE
- wcsncat(path, L"\\*.*", MAXPATH);
-#else
- wcsncat(path, "\\*.*", MAXPATH);
-#endif
- if((d->handle = FindFirstFile(path, &d->wfd)) == INVALID_HANDLE_VALUE){
+ p = catpath(newpath, "*.*", nil);
+ d->handle = FindFirstFile(p, &d->wfd);
+ free(p);
+ if(d->handle == INVALID_HANDLE_VALUE){
free(d);
oserror();
}
- *p = 0;
d->keep = 1;
uif->dir = d;
} else {
uif->dir = nil;
if((uif->fh = CreateFile(
- path,
+ newpath,
fsaccess(mode),
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
- 0)) == INVALID_HANDLE_VALUE){
+ 0)) == INVALID_HANDLE_VALUE)
oserror();
- }
}
- c->qid = wfdtoqid(path, nil);
+ free(uif->path);
+ uif->path = newpath;
+ poperror();
+ c->qid = wfdtoqid(newpath, nil);
c->offset = 0;
c->flag |= COPEN;
c->mode = openmode(mode);
@@ -492,8 +454,8 @@
uif = c->aux;
if(c->flag & COPEN) {
- if(uif->dir){
- if(uif->dir->drivebuf){
+ if(uif->dir != nil){
+ if(uif->dir->drivebuf != nil){
free(uif->dir->drivebuf);
uif->dir->drivebuf = nil;
} else {
@@ -504,6 +466,7 @@
CloseHandle(uif->fh);
}
}
+ free(uif->path);
free(uif);
}
@@ -532,9 +495,8 @@
uif->offset = offset;
}
r = 0;
- if(!ReadFile(fh, va, (DWORD)n, &r, NULL)){
+ if(!ReadFile(fh, va, (DWORD)n, &r, NULL))
oserror();
- }
n = r;
uif->offset += n;
qunlock(&uif->oq);
@@ -567,9 +529,8 @@
uif->offset = offset;
}
w = 0;
- if(!WriteFile(fh, va, (DWORD)n, &w, NULL)){
+ if(!WriteFile(fh, va, (DWORD)n, &w, NULL))
oserror();
- }
n = w;
uif->offset += n;
qunlock(&uif->oq);
@@ -580,15 +541,15 @@
static void
fsremove(Chan *c)
{
- TCHAR path[MAXPATH];
+ Ufsinfo *uif;
- fspath(c, 0, path, MAXPATH);
+ uif = c->aux;
if(c->qid.type & QTDIR){
- if(!RemoveDirectory(path))
- error("RemoveDirectory...");
+ if(!RemoveDirectory(uif->path))
+ oserror();
} else {
- if(!DeleteFile(path))
- error("DeleteFile...");
+ if(!DeleteFile(uif->path))
+ oserror();
}
}
@@ -595,86 +556,69 @@
static int
fswstat(Chan *c, uchar *buf, int n)
{
- TCHAR path[MAXPATH];
- char strs[MAXPATH*3];
+ char strs[MAX_PATH*3];
+ Ufsinfo *uif;
Dir d;
- ulong t;
if (convM2D(buf, n, &d, strs) != n)
error(Ebadstat);
- fspath(c, 0, path, MAXPATH);
- t = pathtype(path);
- if(t != TPATH_FILE)
+ uif = c->aux;
+ if(pathtype(uif->path) != TPATH_FILE)
error(Ebadstat);
/* change name */
if(d.name[0]){
+ wchar_t *base, *newpath;
int l;
- TCHAR newpath[MAXPATH];
- wcsncpy(newpath, path, MAXPATH);
+ base = wstrdup(uif->path);
+ if(waserror()){
+ free(base);
+ nexterror();
+ }
/* replace last path-element with d.name */
- l = wcslen(newpath)-1;
+ l = wcslen(base)-1;
if(l <= 0)
error(Ebadstat);
for(;l>0; l--){
- if(newpath[l-1]=='\\')
+ if(base[l-1]=='\\')
break;
}
if(l <= 0)
error(Ebadstat);
- newpath[l] = 0;
-#ifdef UNICODE
- if(!MultiByteToWideChar(CP_UTF8,0,d.name,-1,&newpath[l],MAXPATH-l-1))
- oserror();
-#else
- wcsncpy(&newpath[l], d.name, MAXPATH-l-1);
-#endif
- if(wcscmp(path, newpath)!=0){
- if(!MoveFile(path, newpath))
+ base[l] = 0;
+ newpath = catpath(base, d.name, nil);
+ free(base), base = newpath;
+ if(wcscmp(uif->path, newpath)!=0){
+ if(!MoveFile(uif->path, newpath))
oserror();
- wcsncpy(path, newpath, MAXPATH);
}
+ free(uif->path);
+ uif->path = newpath;
+ poperror();
}
/* fixme: change attributes */
- c->qid = wfdtoqid(path, nil);
+ c->qid = wfdtoqid(uif->path, nil);
return n;
}
-
-static void
-_fspath(Chan *c, char *ext, char *path, int npath)
+static wchar_t*
+catpath(wchar_t *base, char *cext, wchar_t *wext)
{
- *path = 0;
- strncat(path, uc2name(c), npath);
- if(ext) {
- if(*path)
- strncat(path, "/", npath);
- strncat(path, ext, npath);
- }
- cleanname(path);
- if(*path == '.')
- *path = 0;
-}
+ wchar_t *path;
+ long n, m;
-static void
-fspath(Chan *c, char *ext, TCHAR *path, int npath)
-{
- TCHAR *p;
-#ifdef UNICODE
- char buf[MAXPATH];
- _fspath(c, ext, buf, sizeof(buf));
- if(!MultiByteToWideChar(CP_UTF8,0,buf,-1,path,npath)){
- oserror();
- }
-#else
- _fspath(c, ext, path, npath);
-#endif
- /* make a DOS path */
- for(p=path; *p; p++){
- if(*p == '/')
- *p = '\\';
- }
+ n = wcslen(base);
+ m = wext!=nil ? wcslen(wext) : strlen(cext)*4;
+ path = malloc((n+m+2)*sizeof(wchar_t));
+ memmove(path, base, n*sizeof(wchar_t));
+ if(n > 0 && path[n-1] != '\\') path[n++] = '\\';
+ if(wext != nil)
+ memmove(path+n, wext, m*sizeof(wchar_t));
+ else
+ m = MultiByteToWideChar(CP_UTF8,0,cext,-1,path+n,m);
+ path[n+m] = 0;
+ return path;
}
static int
@@ -700,17 +644,13 @@
long n;
Ufsinfo *uif;
char de[MAX_PATH*3];
- int ndirpath;
- TCHAR dirpath[MAXPATH];
+ wchar_t *p;
i = 0;
uif = c->aux;
errno = 0;
- fspath(c, 0, dirpath, MAXPATH);
- ndirpath = wcslen(dirpath);
- t = pathtype(dirpath);
-
+ t = pathtype(uif->path);
if(uif->offset != offset) {
if(offset != 0)
error("bad offset in fsdirread");
@@ -722,14 +662,11 @@
case TPATH_VOLUME:
case TPATH_FILE:
FindClose(uif->dir->handle);
-#ifdef UNICODE
- wcsncat(dirpath, L"\\*.*", MAXPATH);
-#else
- wcsncat(dirpath, "\\*.*", MAXPATH);
-#endif
- if((uif->dir->handle = FindFirstFile(dirpath, &uif->dir->wfd))==INVALID_HANDLE_VALUE){
+ p = catpath(uif->path, "*.*", nil);
+ uif->dir->handle = FindFirstFile(p, &uif->dir->wfd);
+ free(p);
+ if(uif->dir->handle == INVALID_HANDLE_VALUE)
oserror();
- }
break;
}
uif->dir->keep = 1;
@@ -736,8 +673,6 @@
}
while(i+BIT16SZ < count) {
- char owner[MAXPATH];
-
if(!uif->dir->keep) {
switch(t){
case TPATH_ROOT:
@@ -756,41 +691,21 @@
}
if(t == TPATH_ROOT){
uif->dir->drivep[2] = 0;
-#ifdef UNICODE
WideCharToMultiByte(CP_UTF8,0,uif->dir->drivep,-1,de,sizeof(de),0,0);
-#else
- strncpy(de, uif->dir->drivep, sizeof(de));
-#endif
} else {
-#ifdef UNICODE
WideCharToMultiByte(CP_UTF8,0,uif->dir->wfd.cFileName,-1,de,sizeof(de),0,0);
-#else
- strncpy(de, uif->dir->wfd.cFileName, sizeof(de));
-#endif
}
if(de[0]==0 || isdots(de))
continue;
d.name = de;
- dirpath[ndirpath] = 0;
if(t == TPATH_ROOT){
- wcsncat(dirpath, uif->dir->drivep, MAXPATH);
- wfdtodir(dirpath, &d, nil);
+ p = catpath(uif->path, nil, uif->dir->drivep);
+ wfdtodir(p, &d, nil);
} else {
-#ifdef UNICODE
- wcsncat(dirpath, L"\\", MAXPATH);
-#else
- wcsncat(dirpath, "\\", MAXPATH);
-#endif
- wcsncat(dirpath, uif->dir->wfd.cFileName, MAXPATH);
- wfdtodir(dirpath, &d, &uif->dir->wfd);
+ p = catpath(uif->path, nil, uif->dir->wfd.cFileName);
+ wfdtodir(p, &d, &uif->dir->wfd);
}
-
- if(getfileowner(dirpath, owner, MAXPATH)){
- d.uid = owner;
- d.gid = owner;
- d.muid = owner;
- }
-
+ free(p);
d.type = 'U';
d.dev = c->dev;
n = convD2M(&d, (uchar*)va+i, count-i);
--- a/kern/devroot.c
+++ b/kern/devroot.c
@@ -27,7 +27,7 @@
};
static Dirtab rootdir[Nrootfiles] = {
- "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
+ "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
"boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
"mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555,
};
--- a/main.c
+++ b/main.c
@@ -55,10 +55,8 @@
panic("bind #i: %r");
if(bind("#I", "/net", MBEFORE) < 0)
panic("bind #I: %r");
- if(bind("#U", "/", MAFTER) < 0)
+ if(bind("#U", "/root", MREPL) < 0)
panic("bind #U: %r");
- bind("#A", "/dev", MAFTER);
-
if(open("/dev/cons", OREAD) != 0)
panic("open0: %r");
if(open("/dev/cons", OWRITE) != 1)