Esempio n. 1
0
static char*
gl_dirnext(glob_t* gp, void* handle)
{
	struct dirent*	dp;

	while (dp = (struct dirent*)(*gp->gl_readdir)(handle))
#ifdef D_FILENO
		if (D_FILENO(dp))
#endif
		{
#ifdef D_TYPE
			if (D_TYPE(dp) != DT_UNKNOWN && D_TYPE(dp) != DT_DIR && D_TYPE(dp) != DT_LNK)
				gp->gl_status |= GLOB_NOTDIR;
#endif
			return dp->d_name;
		}
	return 0;
}
Esempio n. 2
0
char*
getpreroot(char* path, const char* cmd)
{
	register int	c;
	register FILE*	fp;
	register char*	p;
	char		buf[PATH_MAX];

	if (!path) path = buf;
	if (cmd)
	{
		sfsprintf(buf, sizeof(buf), "set x `%s= %s - </dev/null 2>&1`\nwhile :\ndo\nshift\ncase $# in\n[012]) break ;;\nesac\ncase \"$1 $2\" in\n\"+ %s\")	echo $3; exit ;;\nesac\ndone\necho\n", PR_SILENT, cmd, PR_COMMAND);
		if (!(fp = popen(buf, "rug"))) return(0);
		for (p = path; (c = getc(fp)) != EOF && c != '\n'; *p++ = c);
		*p = 0;
		pclose(fp);
		if (path == p) return(0);
		return(path == buf ? strdup(path) : path);
	}
	else
	{
		char*		d;
		DIR*		dirp = 0;
		int		namlen;
		int		euid;
		int		ruid;
		struct dirent*	entry;
		struct stat*	cur;
		struct stat*	par;
		struct stat*	tmp;
		struct stat	curst;
		struct stat	parst;
		struct stat	tstst;
		char		dots[PATH_MAX];

		cur = &curst;
		par = &parst;
		if ((ruid = getuid()) != (euid = geteuid())) setuid(ruid);
		if (stat(PR_REAL, cur) || stat("/", par) || cur->st_dev == par->st_dev && cur->st_ino == par->st_ino) ERROR(ENOTDIR);

		/*
		 * like getcwd() but starting at the preroot
		 */

		d = dots;
		*d++ = '/';
		p = path + PATH_MAX - 1;
		*p = 0;
		for (;;)
		{
			tmp = cur;
			cur = par;
			par = tmp;
			if ((d - dots) > (PATH_MAX - 4)) ERROR(ERANGE);
			*d++ = '.';
			*d++ = '.';
			*d = 0;
			if (!(dirp = opendir(dots))) ERROR(errno);
#if !_dir_ok || _mem_dd_fd_DIR
			if (fstat(dirp->dd_fd, par)) ERROR(errno);
#else
			if (stat(dots, par)) ERROR(errno);
#endif
			*d++ = '/';
			if (par->st_dev == cur->st_dev)
			{
				if (par->st_ino == cur->st_ino)
				{
					closedir(dirp);
					*--p = '/';
					if (ruid != euid) setuid(euid);
					if (path == buf) return(strdup(p));
					if (path != p)
					{
						d = path;
						while (*d++ = *p++);
					}
					return(path);
				}
#ifdef D_FILENO
				while (entry = readdir(dirp))
					if (D_FILENO(entry) == cur->st_ino)
					{
						namlen = D_NAMLEN(entry);
						goto found;
					}
#endif
	
				/*
				 * this fallthrough handles logical naming
				 */

				rewinddir(dirp);
			}
			do
			{
				if (!(entry = readdir(dirp))) ERROR(ENOENT);
				namlen = D_NAMLEN(entry);
				if ((d - dots) > (PATH_MAX - 1 - namlen)) ERROR(ERANGE);
				memcpy(d, entry->d_name, namlen + 1);
				if (stat(dots, &tstst)) ERROR(errno);
			} while (tstst.st_ino != cur->st_ino || tstst.st_dev != cur->st_dev);
		found:
			if (*p) *--p = '/';
			if ((p -= namlen) <= (path + 1)) ERROR(ERANGE);
			memcpy(p, entry->d_name, namlen);
			closedir(dirp);
			dirp = 0;
		}
	error:
		if (dirp) closedir(dirp);
		if (ruid != euid) setuid(euid);
	}
	return(0);
}
Esempio n. 3
0
ssize_t
msgsend(int fd, register Msg_call_t* msg, unsigned long call, long ret, int err, void* data)
{
	register struct stat*		sp;
	register struct dirent*		dp;
	register struct dirent*		de;
	register struct statvfs*	vp;
	int				i;
	char*				b;
	char*				e;

	if (call & MSG_ACK)
	{
		if ((fd = csbind(&cs, "udp", msg->ack.addr, msg->ack.port, 0L)) < 0)
			return -1;
		ret = ret == -1 ? ~msg->stamp : msg->stamp;
		err = 0;
		data = 0;
	}
	b = msg->data + MSG_SIZE_SIZE;
	e = msg->data + sizeof(msg->data);
	msgputu(&b, e, call);
	msgputu(&b, e, ret);
	if (ret == -1) msgputu(&b, e, err);
	else if (data) switch (MSG_CALL(call))
	{
	case MSG_getdents:
		dp = (struct dirent*)data;
		de = (struct dirent*)((char*)dp + ret);
		while (dp < de)
		{
			i = D_NAMLEN(dp);
			msgputz(&b, e, dp->d_name, i + 1);
			msgputu(&b, e, D_FILENO(dp));
#if _mem_d_reclen_dirent
			i = dp->d_reclen;
#else
			i = D_RECSIZ(dp, i);
#endif
			dp = (struct dirent*)((char*)dp + i);
		}
		msgputu(&b, e, 0);
		break;
	case MSG_stat:
		sp = (struct stat*)data;
		msgputu(&b, e, sp->st_dev);
		msgputu(&b, e, sp->st_ino);
		msgputu(&b, e, sp->st_mode);
		msgputu(&b, e, sp->st_nlink);
		msgputu(&b, e, sp->st_uid);
		msgputu(&b, e, sp->st_gid);
		msgputu(&b, e, sp->st_size);
		msgputu(&b, e, sp->st_atime);
		msgputu(&b, e, sp->st_mtime);
		msgputu(&b, e, sp->st_ctime);
#if _mem_st_blksize_stat
		msgputu(&b, e, sp->st_blksize);
#else
		msgputu(&b, e, 1024);
#endif
#if _mem_st_blocks_stat
		msgputu(&b, e, sp->st_blocks);
#else
		msgputu(&b, e, sp->st_size ? ((sp->st_size - 1) / 1024 + 1) : 0);
#endif
		break;
	case MSG_statfs:
		vp = (struct statvfs*)data;
		msgputu(&b, e, vp->f_bsize);
		msgputu(&b, e, vp->f_frsize);
		msgputu(&b, e, vp->f_blocks);
		msgputu(&b, e, vp->f_bfree);
		msgputu(&b, e, vp->f_bavail);
		msgputu(&b, e, vp->f_files);
		msgputu(&b, e, vp->f_ffree);
		msgputu(&b, e, vp->f_favail);
#if _mem_f_fsid_statvfs
		msgputu(&b, e, vp->f_fsid);
#else
		msgputu(&b, e, 0);
#endif
#if _mem_f_basetype_statvfs
		msgputz(&b, e, vp->f_basetype, strlen(vp->f_basetype) + 1);
#else
		msgputz(&b, e, "ufs", 4);
#endif
		msgputu(&b, e, vp->f_flag);
		msgputu(&b, e, vp->f_namemax);
#if _mem_f_fstr_statvfs
		msgputz(&b, e, vp->f_fstr, strlen(vp->f_fstr) + 1);
#endif
		break;
	default:
		msgputz(&b, e, data, ret);
		break;
	}
	ret = b - msg->data;
	msgsetsize(msg->data, ret);
	if (cswrite(&cs, fd, msg->data, ret) != ret)
		ret = -1;
	if (call & MSG_ACK)
		close(fd);
	return ret;
}