/* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights * Reserved. This file contains Original Code and/or Modifications of * Original Code as defined in and that are subject to the Apple Public * Source License Version 1.0 (the 'License'). You may not use this file * except in compliance with the License. Please obtain a copy of the * License at http://www.apple.com/publicsource and read it before using * this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License." * * @APPLE_LICENSE_HEADER_END@ */ #import #import #import #import #import #import #import "AMVnode.h" #import "AMMap.h" #import "Server.h" #import "AMString.h" #import #import #import #import "automount.h" #import "log.h" #import @implementation Vnode - (Vnode *)init { [super init]; path = nil; name = nil; link = nil; src = nil; server = nil; map = nil; mounted = NO; fake = NO; mountPathCreated = NO; supernode = nil; subnodes = [[Array alloc] init]; attributes.type = NFDIR; attributes.mode = 0555 | NFSMODE_DIR; attributes.nlink = 1; attributes.uid = 0; attributes.gid = 0; attributes.size = 512; attributes.blocksize = 512; attributes.rdev = 0; attributes.blocks = 1; attributes.fsid = 0; attributes.fileid = 0; gettimeofday((struct timeval *)&attributes.atime, (struct timezone *)0); attributes.mtime = attributes.atime; attributes.ctime = attributes.atime; mntArgs = 0; mntTimeout = GlobalMountTimeout; mountTime = 0; timeToLive = GlobalTimeToLive; nfsStatus = NFS_OK; forcedNFSVersion = 0; forcedProtocol = 0; urlString = [String uniqueString:""]; bzero(&nfsArgs, sizeof(struct nfs_args)); #ifdef __APPLE__ nfsArgs.version = NFS_ARGSVERSION; nfsArgs.addr = (struct sockaddr *)NULL; nfsArgs.addrlen = sizeof(struct sockaddr_in); nfsArgs.sotype = SOCK_DGRAM; nfsArgs.proto = IPPROTO_UDP; nfsArgs.fh = (u_char *)NULL; nfsArgs.fhsize = sizeof(nfs_fh); nfsArgs.flags = NFSMNT_TIMEO | NFSMNT_RETRANS; nfsArgs.wsize = NFS_WSIZE; nfsArgs.rsize = NFS_RSIZE; nfsArgs.readdirsize = NFS_READDIRSIZE; nfsArgs.timeo = GlobalMountTimeout * 10; nfsArgs.retrans = NFS_RETRANS; nfsArgs.maxgrouplist = NFS_MAXGRPS; nfsArgs.readahead = NFS_DEFRAHEAD; nfsArgs.hostname = NULL; #else nfsArgs.addr = (struct sockaddr_in *)NULL; nfsArgs.flags = NFSMNT_TIMEO | NFSMNT_RETRANS; nfsArgs.wsize = NFS_WSIZE; nfsArgs.rsize = NFS_RSIZE; nfsArgs.timeo = GlobalMountTimeout * 10; nfsArgs.retrans = 5; #endif return self; } - (void)dealloc { if (path != nil) [path release]; if (name != nil) [name release]; if (src != nil) [src release]; if (link != nil) [link release]; if (server != nil) [server release]; if (supernode != nil) [supernode release]; if (subnodes != nil) [subnodes release]; [super dealloc]; } - (String *)name { return name; } - (void)setName:(String *)n { if (n == name) return; [name release]; name = [n retain]; if (path != nil) [path release]; path = nil; } - (String *)source { return src; } - (void)setSource:(String *)s { if (s == src) return; [src release]; src = [s retain]; } - (String *)vfsType { return vfsType; } - (void)setVfsType:(String *)s { if (s == vfsType) return; [vfsType release]; vfsType = [s retain]; } - (Server *)server { return server; } - (void)setServer:(Server *)s { if (server == s) return; if (server != nil) [server release]; if (s != nil) server = [s retain]; else server = nil; } - (Map *)map { return map; } - (void)setMap:(Map *)m { map = m; } - (String *)link { return link; } - (void)setLink:(String *)l { if (l == link) return; [link release]; link = [l retain]; } - (void)setUrlString:(String *)n { if (urlString != nil) [urlString release]; urlString = n; [urlString retain]; } - (String *)urlString { return urlString; } - (struct fattr)attributes { return attributes; } - (void)setAttributes:(struct fattr)a { attributes = a; gettimeofday((struct timeval *)&attributes.atime, (struct timezone *)0); attributes.mtime = attributes.atime; } - (ftype)type { return attributes.type; gettimeofday((struct timeval *)&attributes.atime, (struct timezone *)0); } - (void)setType:(ftype)t { attributes.type = t; gettimeofday((struct timeval *)&attributes.atime, (struct timezone *)0); attributes.mtime = attributes.atime; attributes.ctime = attributes.atime; } - (struct nfs_args)nfsArgs { return nfsArgs; } - (unsigned int)forcedNFSVersion { return forcedNFSVersion; } - (unsigned int)forcedProtocol { return forcedProtocol; } - (void)resetTime { gettimeofday((struct timeval *)&attributes.atime, (struct timezone *)0); attributes.mtime = attributes.atime; } - (int)mntArgs { return mntArgs; } - (void)addMntArg:(int)arg { mntArgs |= arg; } - (int)mntTimeout { return mntTimeout; } - (unsigned int)nfsStatus { return nfsStatus; } - (void)setNfsStatus:(unsigned int)s { nfsStatus = s; } - (void)setupOptions:(Array *)o { int i, x, len; char *s; len = [o count]; for (i = 0; i < len; i++) { s = [[o objectAtIndex:i] value]; if (!strcmp(s, "")) continue; else if (!strcmp(s, "rq")) continue; /* XXX */ else if (!strcmp(s, "sw")) continue; /* XXX */ else if (!strcmp(s, "bg")) continue; /* XXX */ else if (!strcmp(s, "-b")) continue; /* XXX */ else if (!strcmp(s, "net")) continue; /* XXX */ else if (!strcmp(s, "rw")) mntArgs &= ~MNT_RDONLY; else if (!strcmp(s, "hard")) mntArgs &= ~NFSMNT_SOFT; else if (!strcmp(s, "ro")) mntArgs |= MNT_RDONLY; else if (!strcmp(s, "rdonly")) mntArgs |= MNT_RDONLY; else if (!strcmp(s, "suid")) mntArgs &= (~MNT_NOSUID); else if (!strcmp(s, "nosuid")) mntArgs |= MNT_NOSUID; else if (!strcmp(s, "exec")) mntArgs &= (~MNT_NOEXEC); else if (!strcmp(s, "noexec")) mntArgs |= MNT_NOEXEC; else if (!strcmp(s, "dev")) mntArgs &= (~MNT_NODEV); else if (!strcmp(s, "nodev")) mntArgs |= MNT_NODEV; else if (!strcmp(s, "union")) mntArgs |= MNT_UNION; else if (!strcmp(s, "sync")) mntArgs |= MNT_SYNCHRONOUS; else if (!strcmp(s, "-s")) nfsArgs.flags |= NFSMNT_SOFT; else if (!strcmp(s, "soft")) nfsArgs.flags |= NFSMNT_SOFT; else if (!strcmp(s, "-i")) nfsArgs.flags |= NFSMNT_INT; else if (!strcmp(s, "intr")) nfsArgs.flags |= NFSMNT_INT; else if (!strcmp(s, "conn")) nfsArgs.flags &= (~NFSMNT_NOCONN); else if (!strcmp(s, "-c")) nfsArgs.flags |= NFSMNT_NOCONN; else if (!strcmp(s, "noconn")) nfsArgs.flags |= NFSMNT_NOCONN; else if (!strcmp(s, "-q")) nfsArgs.flags |= NFSMNT_NQNFS; else if (!strcmp(s, "nqnfs")) nfsArgs.flags |= NFSMNT_NQNFS; else if (!strcmp(s, "-2")) { nfsArgs.flags &= (~NFSMNT_NFSV3); forcedNFSVersion = 2; } else if (!strcmp(s, "nfsv2")) { nfsArgs.flags &= (~NFSMNT_NFSV3); forcedNFSVersion = 2; } else if (!strcmp(s, "-3")) { nfsArgs.flags |= NFSMNT_NFSV3; forcedNFSVersion = 3; } else if (!strcmp(s, "nfsv3")) { nfsArgs.flags |= NFSMNT_NFSV3; forcedNFSVersion = 3; } else if (!strcmp(s, "-K")) nfsArgs.flags |= NFSMNT_KERB; else if (!strcmp(s, "kerb")) nfsArgs.flags |= NFSMNT_KERB; else if (!strcmp(s, "-d")) nfsArgs.flags |= NFSMNT_DUMBTIMR; else if (!strcmp(s, "dumbtimer")) nfsArgs.flags |= NFSMNT_DUMBTIMR; else if (!strcmp(s, "-P")) nfsArgs.flags |= NFSMNT_RESVPORT; else if (!strcmp(s, "resvport")) nfsArgs.flags |= NFSMNT_RESVPORT; else if (!strcmp(s, "-l")) nfsArgs.flags |= NFSMNT_RDIRPLUS; else if (!strcmp(s, "rdirplus")) nfsArgs.flags |= NFSMNT_RDIRPLUS; #ifdef __APPLE__ else if (!strcmp(s, "-U")) { forcedProtocol = IPPROTO_UDP; nfsArgs.proto = IPPROTO_UDP; } else if (!strcmp(s, "UDP")) { forcedProtocol = IPPROTO_UDP; nfsArgs.proto = IPPROTO_UDP; } else if (!strcmp(s, "udp")) { forcedProtocol = IPPROTO_UDP; nfsArgs.proto = IPPROTO_UDP; } else if (!strcmp(s, "-T")) { forcedProtocol = IPPROTO_TCP; nfsArgs.proto = IPPROTO_TCP; } else if (!strcmp(s, "TCP")) { forcedProtocol = IPPROTO_TCP; nfsArgs.proto = IPPROTO_TCP; } else if (!strcmp(s, "tcp")) { forcedProtocol = IPPROTO_TCP; nfsArgs.proto = IPPROTO_TCP; } else if (!strncmp(s, "-I=", 3)) { x = atoi(s+3); if (x <= 0) x = NFS_READDIRSIZE; nfsArgs.readdirsize = x; } else if (!strncmp(s, "-a=", 3)) { x = atoi(s+3); if (x <= 0) x = NFS_DEFRAHEAD; nfsArgs.readahead = x; } else if (!strncmp(s, "-g=", 3)) { x = atoi(s+3); if (x <= 0) x = NFS_MAXGRPS; nfsArgs.maxgrouplist = x; } #endif else if (!strncmp(s, "-w=", 3)) { nfsArgs.flags |= NFSMNT_WSIZE; x = atoi(s+3); if (x <= 0) x = NFS_WSIZE; nfsArgs.wsize = x; } else if (!strncmp(s, "wsize=", 6)) { nfsArgs.flags |= NFSMNT_WSIZE; x = atoi(s+6); if (x <= 0) x = NFS_WSIZE; nfsArgs.wsize = x; } else if (!strncmp(s, "-r=", 3)) { nfsArgs.flags |= NFSMNT_RSIZE; x = atoi(s+3); if (x <= 0) x = NFS_RSIZE; nfsArgs.rsize = x; } else if (!strncmp(s, "rsize=", 6)) { nfsArgs.flags |= NFSMNT_RSIZE; x = atoi(s+6); if (x <= 0) x = NFS_RSIZE; nfsArgs.rsize = x; } else if (!strncmp(s, "-t=", 3)) { nfsArgs.flags |= NFSMNT_TIMEO; x = atoi(s+3); if (x <= 0) x = 7; nfsArgs.timeo = x; } else if (!strncmp(s, "timeo=", 6)) { nfsArgs.flags |= NFSMNT_TIMEO; x = atoi(s+6); if (x <= 0) x = 7; nfsArgs.timeo = x; } else if (!strncmp(s, "-x=", 3)) { nfsArgs.flags |= NFSMNT_TIMEO; x = atoi(s+3); if (x <= 0) x = 3; nfsArgs.retrans = x; } else if (!strncmp(s, "retrans=", 8)) { nfsArgs.flags |= NFSMNT_TIMEO; x = atoi(s+8); if (x <= 0) x = 3; nfsArgs.retrans = x; } else if (!strncmp(s, "mnttimeo=", 9)) { x = atoi(s+9); if (x <= 0) x = GlobalMountTimeout; mntTimeout = x; } else if (!strncmp(s, "ttl=", 4)) { x = atoi(s+4); if (x < 0) x = GlobalTimeToLive; timeToLive = x; } else if (!strncmp(s, "arch==", 6)) {} else if (!strncmp(s, "arch!=", 6)) {} else if (!strncmp(s, "endian==", 8)) {} else if (!strncmp(s, "endian!=", 8)) {} else if (!strncmp(s, "domain==", 8)) {} else if (!strncmp(s, "domain!=", 8)) {} else if (!strncmp(s, "host==", 6)) {} else if (!strncmp(s, "host!=", 6)) {} else if (!strncmp(s, "network==", 9)) {} else if (!strncmp(s, "network!=", 9)) {} else if (!strncmp(s, "netgroup==", 10)) {} else if (!strncmp(s, "netgroup!=", 10)) {} else if (!strncmp(s, "os==", 4)) {} else if (!strncmp(s, "os!=", 4)) {} else if (!strncmp(s, "osvers==", 8)) {} else if (!strncmp(s, "osvers!=", 8)) {} else if (!strncmp(s, "osvers<", 7)) {} else if (!strncmp(s, "osvers<=", 8)) {} else if (!strncmp(s, "osvers>", 7)) {} else if (!strncmp(s, "osvers>=", 8)) {} else if (!strncmp(s, "url==", 5)) {} else if (!strcmp(s, "noquota")) {} else if (!strcmp(s, "grpid")) {} else { sys_msg(debug, LOG_DEBUG, "%s: option %s ignored", [[self path] value], s); } } } - (unsigned int)mode { return attributes.mode; } - (void)setMode:(unsigned int)m { attributes.mode = m; } - (unsigned int)nodeID { return attributes.fileid; } - (void)setNodeID:(unsigned int)n { attributes.fileid = n; } - (int) checkPathIsMount:(char *)apath { struct stat statbuf; static dev_t rootDevNode = 0; sys_msg(debug_mount, LOG_DEBUG, "Checking path %s", apath); if (!rootDevNode) { struct stat rootbuf; stat("/", &rootbuf); rootDevNode = rootbuf.st_dev; } if (!stat(apath, &statbuf)) { sys_msg(debug_mount, LOG_DEBUG, "%s stat succeeded", apath); if (statbuf.st_dev != rootDevNode) { return TRUE; } } else { sys_msg(debug_mount, LOG_DEBUG, "%s stat failed, %s", apath, strerror(errno)); } return FALSE; } - (BOOL)mounted { /* String *urlMountType; urlMountType = [String uniqueString:"url"]; sys_msg(debug_mount, LOG_DEBUG, "checking type %s for %s", [[self vfsType] value], [[self link] value]); if ([[self vfsType] equal:urlMountType] || ![self vfsType]) { char mountDir[1024]; mounted = [self checkPathIsMount:[[self link] value]]; } [urlMountType release]; */ return mounted; } - (void)resetMountTime { struct timeval tv; if (mounted) { gettimeofday(&tv, NULL); mountTime = tv.tv_sec; } else mountTime = 0; } - (void)setMounted:(BOOL)m { mounted = m; [self resetMountTime]; } - (BOOL)fakeMount { return fake; } - (void)setFakeMount:(BOOL)m { fake = m; } - (unsigned int)mountTime { return mountTime; } - (unsigned int)mountTimeToLive { return timeToLive; } - (BOOL)mountPathCreated { return mountPathCreated; } - (void)setMountPathCreated:(BOOL)m { mountPathCreated = m; } - (void)getFileHandle:(nfs_fh *)fh { bzero(fh, sizeof(nfs_fh)); bcopy(&attributes.fileid, fh, sizeof(unsigned int)); } - (Vnode *)lookup:(String *)n { int i, count; Vnode *sub; if (strcmp([n value], ".") == 0) return self; if (strcmp([n value], "..") == 0) { if (supernode == nil) return self; return supernode; } count = [subnodes count]; for (i = 0; i < count; i++) { sub = [subnodes objectAtIndex:i]; if ([n equal:[sub name]]) return sub; } return nil; } - (Vnode *)parent { return supernode; } - (void)setParent:(Vnode *)p { if (supernode == p) return; if (supernode != nil) [supernode release]; supernode = [p retain]; if (path != nil) [path release]; path = nil; } - (Array *)children { return (Array *)subnodes; } - (void)addChild:(Vnode *)child { if ([subnodes containsObject:child]) return; [subnodes addObject:child]; [child setParent:self]; } - (void)removeChild:(Vnode *)child { if (child == nil) return; if (![subnodes containsObject:child]) { sys_msg(debug, LOG_ERR, "Attempt to remove node %d (%s) from non-parent node %d (%s)", [child nodeID], [[child name] value], [self nodeID], [[self name] value]); return; } [subnodes removeObject:child]; } - (Array *)dirlist { int i, count; Array *list; count = [subnodes count]; list = [[Array alloc] init]; [list addObject:self]; if (supernode == nil) [list addObject:self]; else [list addObject:supernode]; for (i = 0; i < count; i++) { [list addObject:[subnodes objectAtIndex:i]]; } return list; } - (String *)path { String *n; char *s; if (path != nil) return path; if (supernode == nil) { path = [String uniqueString:"/"]; return path; } n = [supernode path]; if (!strcmp([n value], "/")) { s = malloc(1 + [name length] + 1); sprintf(s, "/%s", [name value]); } else { s = malloc([n length] + 1 + [name length] + 1); sprintf(s, "%s/%s", [n value], [name value]); } path = [String uniqueString:s]; free(s); return path; } @end