예제 #1
0
파일: partition.c 프로젝트: openafs/openafs
int
VAttachPartitions(void)
{
    int errors = 0;
    int nmounts;
    struct vmount *vmountp;

    if ((nmounts = getmount(&vmountp)) <= 0) {
	Log("Problems in getting # of mount entries(getmount)\n");
	exit(-1);
    }
    for (; nmounts;
	 nmounts--, vmountp =
	 (struct vmount *)((int)vmountp + vmountp->vmt_length)) {
	char *part = vmt2dataptr(vmountp, VMT_STUB);

	if (vmountp->vmt_flags & (MNT_READONLY | MNT_REMOVABLE | MNT_REMOTE))
	    continue;		/* Ignore any "special" partitions */

#ifdef AFS_AIX42_ENV
#ifndef AFS_NAMEI_ENV
	{
	    struct superblock fs;
	    /* The Log statements are non-sequiters in the SalvageLog and don't
	     * even appear in the VolserLog, so restrict them to the FileLog.
	     */
	    if (ReadSuper(&fs, vmt2dataptr(vmountp, VMT_OBJECT)) < 0) {
		if (programType == fileServer)
		    Log("Can't read superblock for %s, ignoring it.\n", part);
		continue;
	    }
	    if (IsBigFilesFileSystem(&fs)) {
		if (programType == fileServer)
		    Log("%s is a big files filesystem, ignoring it.\n", part);
		continue;
	    }
	}
#endif
#endif

	/* Skip this Partition? */
	if (VIsNeverAttach(part))
	    continue;

	/* If we're going to always attach this partition, do it later. */
	if (VIsAlwaysAttach(part, NULL))
	    continue;

	if (VCheckPartition(part, vmt2dataptr(vmountp, VMT_OBJECT), 0) < 0)
	    errors++;
    }

    /* Process the always-attach partitions, if any. */
    VAttachPartitions2();

    return errors;
}
예제 #2
0
static

#endif

char*
pathreal(const char* apath, register int type, struct stat* st)
{
	char*			path = (char*)apath;
	register char*		sp;
	register char*		cp;
	register char*		ip;
	Table_t*		safe;
	int			oerrno = errno;
	int			opaqued = 0;
	int			len;
	int			vir;
	int			safesize;
	int			safe_dir;
	long			visits;
	char			buf[PATH_MAX + 1];

	static struct stat	stbuf;
	static struct stat	tsbuf;

	state.path.level = state.path.synthesize = state.path.nlinks = 0;
	if (!path)
	{
		errno = EFAULT;
		return 0;
	}
	initialize();
	if (state.in_2d)
	{
		if (!st || (!state.level || *path == '/') && !LSTAT(path, st))
			return path;
		if (state.level && streq(path, ".") && !CHDIR(state.pwd))
		{
			state.level = 0;
			return path;
		}
		return 0;
	}
#if FS
	if (mounted() && (sp = fsreal(state.path.monitor, MSG_stat, state.path.mount)))
		apath = (char*)(path = sp);
#endif

	/*
	 * handle null path, . and / separately
	 */

	if (safe = state.safe ? &state.vsafe : (Table_t*)0)
	{
		type |= P_ABSOLUTE;
		if (!(safesize = state.safe->servicesize))
			safesize = strlen(state.safe->service);
	}
	else
		type &= ~P_SAFE;
 again:
	if (!*path)
	{
		errno = ENOENT;
		return 0;
	}
	cp = sp = path;
	state.path.synthesize = state.path.linksize = 0;
	if (!st)
		st = &stbuf;

	/*
	 * check if virtual dir has been created by another process
	 * only P_PATHONLY|P_TOP calls (usually create or modify link) and
	 * references to "." are checked for performance
	 */

	if (state.level > 0 && state.pwd && ((type & (P_PATHONLY|P_TOP)) && *sp != '/' || *sp == '.' && sp[1] == 0))
	{
		if (!CHDIR(state.pwd))
			state.level = 0;
		else if (!(type & (P_PATHONLY|P_TOP)))
		{
			len = 0;
			state.path.level += (state.path.synthesize = state.level);
			sp = strcpy(state.path.name, state.pwd);
			goto skip;
		}
	}
	if (!state.pwd || sp[1] == 0 && (*sp == '.' || *sp == '/' && !safe))
	{
		if (st != &stbuf && LSTAT(sp, st))
			return 0;
		if (*sp == '/' || !state.pwd && (type & P_PATHONLY))
			strncpy(state.path.name, sp, PATH_MAX);
		else if (!state.pwd)
		{
			/*
			 * treat the current directory as if were empty
			 */

			errno = ENOENT;
			return 0;
		}
		else
			strncpy(state.path.name, state.pwd, PATH_MAX);
		errno = oerrno;
		return state.path.name;
	}

	/*
	 * put absolute pathname into state.path
	 */

	safe_dir = 0;
	if (*path != '/')
	{
		strcpy(state.path.name, state.pwd);
		sp = state.path.name + state.pwdsize;
		*sp++ = '/';
		if (safe && state.pwdsize >= safesize && !strncmp(state.pwd, state.safe->service, safesize) && (!state.pwd[safesize] || state.pwd[safesize] == '/'))
			safe_dir = safesize;
	}
	else
		sp = state.path.name;
	ip = state.path.name + elementsof(state.path.name);
	while (sp < ip && (*sp = *cp++))
		sp++;
	if (type & P_DOTDOT)
		strcpy(sp, "/..");
	sp = state.path.name;
	if (!(ip = pathcanon(sp + safe_dir, sizeof(state.path.name) - safe_dir, 0)))
	{
		errno = ENOENT;
		return 0;
	}
	if (type & (P_DOTDOT|P_NOSLASH))
	{
		/*
		 * remove trailing slashes
		 */

		while (*--ip == '/');
		*++ip = 0;
	}
	else if ((type & P_SLASH) && *(ip - 1) != '/')
		*ip++ = '/';
	if (*(ip - 1) == '/' && ip - sp > 1)
	{
		/*
		 * trailing slash is equivalent to trailing slash-dot
		 * this forces the common-sense interpretation
		 */
#if DEBUG
		if (!(state.test & 010))
#endif
		*ip++ = '.';
		*ip = 0;
	}
	len = ip - sp;

	/*
	 * try to use relative path
	 */

	if (!(type & (P_LSTAT|P_READLINK)))
	{
		for (ip = state.pwd; *ip && *ip == *sp++; ip++);
		if (*ip != 0 || *sp && *sp != '/' || state.level < 0)
			sp = state.path.name;
		else
		{
			state.path.level += (state.path.synthesize = state.level);
			if (state.level && !(type & P_PATHONLY) && st == &stbuf)
			{
				sp = state.path.name;
				len -= state.pwdsize;
			}
			else if (type & P_ABSOLUTE)
				sp = state.path.name;
			else if (*sp == '/')
				sp++;
		}
		if (*sp == 0)
			sp = state.dot;
	}
 skip:
	if ((type & P_NOOPAQUE) && !LSTAT(sp, st) && checkopaque(sp, st))
	{
		message((-1, "%s: remove opaque", sp));
		UNLINK(sp);
		opaqued = 1;
	}
	if (safe && *sp == '/')
	{
		state.path.table = safe;
		cp = pathnext(sp, NiL, NiL);
		state.path.table = safe = 0;
		if (cp)
		{
			state.path.level = 0;
			path = strcpy(buf, sp);
			message((-5, "pathreal: == safe map %s", path));
			type &= ~(P_DOTDOT|P_SAFE);
			goto again;
		}
		if (!*(sp + 1))
		{
			strncpy(sp, state.safe->service, safesize);
			sp[safesize] = 0;
		}
		else if (strncmp(sp, state.safe->service, safesize) || sp[safesize] && sp[safesize] != '/')
		{
			if (*path != '/' && safe_dir)
			{
				errno = EPERM;
				return 0;
			}
			if (sp[1])
				strcpy(buf, sp);
			else
				*buf = 0;
			len = sfsprintf(sp, sizeof(state.path.name), "%-*s%s", safesize, state.safe->service, buf);
			message((-5, "pathreal: == safe next %s", sp));
			if (!pathnext(sp, NiL, NiL))
			{
				errno = EPERM;
				return 0;
			}
		}
		else
			type &= ~P_SAFE;
	}
	if ((type & P_SAFE) && state.path.level)
	{
		errno = EPERM;
		return 0;
	}
	if (type & P_PATHONLY)
	{
		errno = oerrno;
		return sp;
	}
	visits = 0;
	vir = 1;
	while (LSTAT(sp, st))
	{
		if (vir)
		{
			if (apath[0] == '.' && apath[1] == '.' && apath[2] == '.' && !apath[3])
			{
				if (state.level > 0)
				{
					message((-1, "pathreal: %s => %s", apath, sp));
					LSTAT(".", st);
					return sp;
				}
				errno = ENOENT;
				return 0;
			}
			vir = 0;
		}
		if (errno == ENOTDIR)
		{
			/*
			 * check for version instance
			 */

			cp = ip = sp + strlen(sp);
			while (ip > sp && *--ip != '/');
			if (ip < sp)
				return 0;
			while (ip > sp && *--ip == '/');
			if (ip < sp)
				return 0;
			while (ip > sp && *--ip != '/');
			if (*ip == '/')
				ip++;
			while (cp >= ip)
			{
				cp[4] = *cp;
				cp--;
			}
			memcpy(ip, state.opaque, 4);
			if (!LSTAT(sp, st))
				break;
			errno = ENOTDIR;
			return 0;
		}

		if (errno != ENOENT || opaqued)
			return 0;
#if FS
		/*
		 * check user mount
		 */

		if (visits)
		{
			Mount_t*	mp;
			const char*	up;

			if ((mp = getmount(sp, &up)) && (mp->fs->flags & FS_NAME) && (sp = fsreal(mp, MSG_open, (char*)up)) && !LSTAT(sp, st))
				break;
		}
#endif

		/*
		 * search down the viewpath
		 */

		if (type & P_SAFE)
		{
			errno = EPERM;
			return 0;
		}
		if (!pathnext(state.path.name, NiL, &visits))
			return 0;
		sp = state.path.name;
		if (!(type & P_ABSOLUTE))
		{
			/*
			 * try to use relative path
			 */

			for (ip = state.pwd; *ip && *ip == *sp++; ip++);
			if (*ip == 0 && *sp == '/')
				sp++;
			else
				sp = state.path.name;
		}
		if (*sp == 0)
			sp = state.dot;
	}
	if (st->st_nlink > 1 && checkopaque(sp, st))
		return 0;
	if ((type & P_TOP) && state.path.level)
	{
		int	rfd;
		int	wfd;

		if ((rfd = OPEN(sp, O_RDONLY, 0)) < 0)
			sp = 0;
		else
		{
			tsbuf = *st;
			wfd = open(apath, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, st->st_mode & S_IPERM);
			*st = tsbuf;
			if (wfd < 0)
				sp = 0;
			else 
			{
				if (fs3d_copy(rfd, wfd, st))
					sp = 0;
				CLOSE(wfd);
			}
			CLOSE(rfd);
		}
		if (!sp)
		{
			errno = EROFS;
			return 0;
		}
		if (st == &stbuf)
			st = 0;
		return pathreal(apath, P_PATHONLY, st);
	}
	IVIEW(st, state.path.level);
	if (state.path.synthesize)
	{
		if (state.path.level < state.level)
		{
			if (len)
			{
				ip  = state.path.name + strlen(state.path.name) - len;
				len = *ip;
				*ip = 0;
			}
			if (!CHDIR(state.path.name))
				state.level = state.path.level;
			message((-1, "chdir=%s level=%d", state.path.name, state.level));
			*ip = len;
		}
		else if (S_ISDIR(st->st_mode))
		{
			int		mask;
			static int	uid = -1;
			static int	gid;

			umask(mask = umask(0));
			st->st_mode = (st->st_mode | (S_IRWXU|S_IRWXG|S_IRWXO)) & ~(mask & (S_IRWXU|S_IRWXG|S_IRWXO));
			if (uid == -1)
			{
				uid = geteuid();
				gid = getegid();
			}
			st->st_uid = uid;
			st->st_gid = gid;
		}
	}
	ip = sp;

	/*
	 * symbolic links handled specially
	 * get filename from pathname
	 */

	if (S_ISLNK(st->st_mode) && (len = checklink(sp, st, type)) > 1 && !(type & (P_LSTAT|P_READLINK)) && state.path.nlinks++ < MAXSYMLINKS)
	{
		path = strcpy(buf, state.path.name);
		message((-1, "pathreal: == again %s", path));
		if (*path != '/')
			state.path.level = 0;
		type &= ~(P_DOTDOT|P_SAFE);
		goto again;
	}
#if VCS && defined(VCS_REAL)
	VCS_REAL(state.path.name, st);
#endif
	errno = oerrno;
	return sp;
}
예제 #3
0
파일: devname.c 프로젝트: adeason/openafs
/* ensure that we don't have a "/" instead of a "/dev/rxd0a" type of device.
 * returns pointer to static storage; copy it out quickly!
 */
char *
vol_DevName(dev_t adev, char *wpath)
{
    static char pbuffer[128];
    char pbuf[128], *ptr;
#ifdef	AFS_SUN5_ENV
    struct mnttab mnt;
    FILE *mntfile;
#else
#if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
    struct mntent *mntent;
    FILE *mfd;
#else
    struct fstab *fsent;
#endif
#endif
#ifdef	AFS_AIX_ENV
    int nmounts;
    struct vmount *vmountp;
#endif

#ifdef	AFS_AIX_ENV
    if ((nmounts = getmount(&vmountp)) <= 0) {
	return NULL;
    }
    for (; nmounts;
	 nmounts--, vmountp =
	 (struct vmount *)((int)vmountp + vmountp->vmt_length)) {
	char *part = vmt2dataptr(vmountp, VMT_STUB);
#else
#ifdef	AFS_SUN5_ENV
    if (!(mntfile = fopen(MNTTAB, "r"))) {
	return NULL;
    }
    while (!getmntent(mntfile, &mnt)) {
	char *part = mnt.mnt_mountp;
#else
#if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
#ifdef AFS_LINUX22_ENV
    if ((mfd = setmntent("/proc/mounts", "r")) == NULL) {
	if ((mfd = setmntent("/etc/mtab", "r")) == NULL) {
	    return NULL;
	}
    }
#else
    if ((mfd = setmntent(MOUNTED /*MNTTAB*/, "r")) == NULL) {
	return NULL;
    }
#endif
    while ((mntent = getmntent(mfd))) {
	char *part = mntent->mnt_dir;
#else
    setfsent();
    while ((fsent = getfsent())) {
	char *part = fsent->fs_file;
#endif
#endif /* AFS_SGI_ENV */
#endif
	struct stat status;
#ifdef	AFS_AIX_ENV
	if (vmountp->vmt_flags & (MNT_READONLY | MNT_REMOVABLE | MNT_REMOTE))
	    continue;		/* Ignore any "special" partitions */
#else
#ifdef	AFS_SUN5_ENV
	/* Ignore non ufs or non read/write partitions */
	if ((strcmp(mnt.mnt_fstype, "ufs") != 0)
	    || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
	    continue;
#else
#if defined(AFS_LINUX22_ENV)
	if (strcmp(mntent->mnt_type, "ext2"))
	    continue;
#else
#if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV)
	if (!hasmntopt(mntent, MNTOPT_RW))
	    continue;
#else
	if (strcmp(fsent->fs_type, "rw") != 0)
	    continue;		/* Ignore non read/write partitions */
#endif /* AFS_LINUX22_ENV */
#endif /* AFS_SGI_ENV */
#endif
#endif
	/* Only keep track of "/vicepx" partitions since it can get hairy when NFS mounts are involved.. */
	if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
	    continue;		/* Non /vicepx; ignore */
	}
	if (stat(part, &status) == -1) {
	    continue;
	}
#if !defined(AFS_SGI_XFS_IOPS_ENV) && !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
	if ((status.st_ino !=
	     ROOTINO) /*|| ((status.st_mode & S_IFMT) != S_IFBLK) */ ) {
	    continue;
	}
#endif
	if (status.st_dev == adev) {
#ifdef	AFS_AIX_ENV
	    strcpy(pbuffer, vmt2dataptr(vmountp, VMT_OBJECT));
#else
#ifdef	AFS_SUN5_ENV
	    strcpy(pbuffer, mnt.mnt_special);
#else
#if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
	    strcpy(pbuffer, mntent->mnt_fsname);
#else
	    strcpy(pbuffer, fsent->fs_spec);
#endif
#endif /* AFS_SGI_ENV */
#endif
	    if (wpath) {
		strcpy(pbuf, pbuffer);
		ptr = (char *)strrchr(pbuf, OS_DIRSEPC);
		if (ptr) {
		    *ptr = '\0';
		    strcpy(wpath, pbuf);
		} else
		    return NULL;
	    }
	    ptr = (char *)strrchr(pbuffer, OS_DIRSEPC);
	    if (ptr) {
		strcpy(pbuffer, ptr + 1);
		return pbuffer;
	    } else
		return NULL;
	}
    }
#ifdef	AFS_SUN5_ENV
    (void)fclose(mntfile);
#else
#if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
    endmntent(mfd);
#else
#ifndef	AFS_AIX_ENV
    endfsent();
#endif
#endif
#endif /* AFS_SGI_ENV */
    return NULL;
}

/* Search for the raw device name. Will put an "r" in front of each
 * directory and file entry of the pathname until we find a character
 * device.
 */
char *
afs_rawname(char *devfile)
{
    static char rawname[100];
    struct stat statbuf;
    int code, i;

    i = strlen(devfile);
    while (i >= 0) {
	strcpy(rawname, devfile);
	if (devfile[i] == OS_DIRSEPC) {
	    rawname[i + 1] = 'r';
	    rawname[i + 2] = 0;
	    strcat(rawname, &devfile[i + 1]);
	}

	code = stat(rawname, &statbuf);
	if (!code && S_ISCHR(statbuf.st_mode))
	    return rawname;

	while ((--i >= 0) && (devfile[i] != OS_DIRSEPC));
    }

    return NULL;
}