Пример #1
0
void wxDatabaseConfig::GetChildren(dbentry& parent, dbentries* groups, dbentries* entries, bool recursive)
{ 
	dbentries wild;
	m_self->FindEntries(parent.path+wxCONFIG_PATH_SEPARATOR+'%', wild);

	for (dbentries::iterator it = wild.begin(); it != wild.end(); ++it)
	{
		wxString localpath(it->path.Right(it->path.Length()-parent.path.Length()-1));
		if (!recursive && wxStrchr(localpath, wxCONFIG_PATH_SEPARATOR)) continue;
		if (it->isgroup)
		{
			if (groups == NULL) continue;
			groups->push_back(*it);
		}
		else
		{
			if (entries == NULL) continue;
			entries->push_back(*it);
		}
	}
}
Пример #2
0
/*
 * The additional flag, LOOKUP_CHECKREAD, is used to enforce artificial
 * constraints in order to be standards compliant.  For example, if we have
 * the cached path of '/foo/bar', and '/foo' has permissions 100 (execute
 * only), then we can legitimately look up the path to the current working
 * directory without needing read permission.  Existing standards tests,
 * however, assume that we are determining the path by repeatedly looking up
 * "..".  We need to keep this behavior in order to maintain backwards
 * compatibility.
 */
static int
vnodetopath_common(vnode_t *vrootp, vnode_t *vp, char *buf, size_t buflen,
    cred_t *cr, int flags)
{
	pathname_t pn, rpn;
	int ret, len;
	vnode_t *compvp, *pvp, *realvp;
	proc_t *p = curproc;
	char path[MAXNAMELEN];
	int doclose = 0;

	/*
	 * If vrootp is NULL, get the root for curproc.  Callers with any other
	 * requirements should pass in a different vrootp.
	 */
	if (vrootp == NULL) {
		mutex_enter(&p->p_lock);
		if ((vrootp = PTOU(p)->u_rdir) == NULL)
			vrootp = rootdir;
		VN_HOLD(vrootp);
		mutex_exit(&p->p_lock);
	} else {
		VN_HOLD(vrootp);
	}

	/*
	 * This is to get around an annoying artifact of the /proc filesystem,
	 * which is the behavior of {cwd/root}.  Trying to resolve this path
	 * will result in /proc/pid/cwd instead of whatever the real working
	 * directory is.  We can't rely on VOP_REALVP(), since that will break
	 * lofs.  The only difference between procfs and lofs is that opening
	 * the file will return the underling vnode in the case of procfs.
	 */
	if (vp->v_type == VDIR && VOP_REALVP(vp, &realvp, NULL) == 0 &&
	    realvp != vp) {
		VN_HOLD(vp);
		if (VOP_OPEN(&vp, FREAD, cr, NULL) == 0)
			doclose = 1;
		else
			VN_RELE(vp);
	}

	pn_alloc(&pn);

	/*
	 * Check to see if we have a cached path in the vnode.
	 */
	mutex_enter(&vp->v_lock);
	if (vp->v_path != NULL) {
		(void) pn_set(&pn, vp->v_path);
		mutex_exit(&vp->v_lock);

		pn_alloc(&rpn);

		/* We should only cache absolute paths */
		ASSERT(pn.pn_buf[0] == '/');

		/*
		 * If we are in a zone or a chroot environment, then we have to
		 * take additional steps, since the path to the root might not
		 * be readable with the current credentials, even though the
		 * process can legitmately access the file.  In this case, we
		 * do the following:
		 *
		 * lookuppnvp() with all privileges to get the resolved path.
		 * call localpath() to get the local portion of the path, and
		 * continue as normal.
		 *
		 * If the the conversion to a local path fails, then we continue
		 * as normal.  This is a heuristic to make process object file
		 * paths available from within a zone.  Because lofs doesn't
		 * support page operations, the vnode stored in the seg_t is
		 * actually the underlying real vnode, not the lofs node itself.
		 * Most of the time, the lofs path is the same as the underlying
		 * vnode (for example, /usr/lib/libc.so.1).
		 */
		if (vrootp != rootdir) {
			char *local = NULL;
			VN_HOLD(rootdir);
			if (lookuppnvp(&pn, &rpn, FOLLOW,
			    NULL, &compvp, rootdir, rootdir, kcred) == 0) {
				local = localpath(rpn.pn_path, vrootp,
				    kcred);
				VN_RELE(compvp);
			}

			/*
			 * The original pn was changed through lookuppnvp().
			 * Set it to local for next validation attempt.
			 */
			if (local) {
				(void) pn_set(&pn, local);
			} else {
				goto notcached;
			}
		}

		/*
		 * We should have a local path at this point, so start the
		 * search from the root of the current process.
		 */
		VN_HOLD(vrootp);
		if (vrootp != rootdir)
			VN_HOLD(vrootp);
		ret = lookuppnvp(&pn, &rpn, FOLLOW | flags, NULL,
		    &compvp, vrootp, vrootp, cr);
		if (ret == 0) {
			/*
			 * Check to see if the returned vnode is the same as
			 * the one we expect.  If not, give up.
			 */
			if (!vn_compare(vp, compvp) &&
			    !vnode_match(vp, compvp, cr)) {
				VN_RELE(compvp);
				goto notcached;
			}

			VN_RELE(compvp);

			/*
			 * Return the result.
			 */
			if (buflen <= rpn.pn_pathlen)
				goto notcached;

			bcopy(rpn.pn_path, buf, rpn.pn_pathlen + 1);
			pn_free(&pn);
			pn_free(&rpn);
			VN_RELE(vrootp);
			if (doclose) {
				(void) VOP_CLOSE(vp, FREAD, 1, 0, cr, NULL);
				VN_RELE(vp);
			}
			return (0);
		}

notcached:
		pn_free(&rpn);
	} else {
		mutex_exit(&vp->v_lock);
	}

	pn_free(&pn);

	if (vp->v_type != VDIR) {
		/*
		 * If we don't have a directory, try to find it in the dnlc via
		 * reverse lookup.  Once this is found, we can use the regular
		 * directory search to find the full path.
		 */
		if ((pvp = dnlc_reverse_lookup(vp, path, MAXNAMELEN)) != NULL) {
			/*
			 * Check if we have read privilege so, that
			 * we can lookup the path in the directory
			 */
			ret = 0;
			if ((flags & LOOKUP_CHECKREAD)) {
				ret = VOP_ACCESS(pvp, VREAD, 0, cr, NULL);
			}
			if (ret == 0) {
				ret = dirtopath(vrootp, pvp, buf, buflen,
				    flags, cr);
			}
			if (ret == 0) {
				len = strlen(buf);
				if (len + strlen(path) + 1 >= buflen) {
					ret = ENAMETOOLONG;
				} else {
					if (buf[len - 1] != '/')
						buf[len++] = '/';
					bcopy(path, buf + len,
					    strlen(path) + 1);
				}
			}

			VN_RELE(pvp);
		} else
			ret = ENOENT;
	} else
		ret = dirtopath(vrootp, vp, buf, buflen, flags, cr);

	VN_RELE(vrootp);
	if (doclose) {
		(void) VOP_CLOSE(vp, FREAD, 1, 0, cr, NULL);
		VN_RELE(vp);
	}

	return (ret);
}
Пример #3
0
static int
print_directory(int level, char *basedir)
{
	const char *path;
	FILEOP *fileop = NULL;
	FILE *op = NULL;
	int flist_items = 0;
	int count = 0;

	if (level > 0) {
		char name[MAXPATHLEN];

		snprintf(name, sizeof(name), "%s/files/%s.%s", distpath, path2fid(basedir), HTML);
		fileop = open_output_file(name, 0);
		op = get_descripter(fileop);
		print_directory_header(op, level, basedir);
		if (tree_view) {
			char *target = (Fflag) ? "mains" : "_top";

			strbuf_puts(files, dir_begin);
			strbuf_puts(files, gen_href_begin_with_title_target("files", path2fid(basedir), HTML, NULL, NULL, target));
			strbuf_puts(files, full_path ? removedotslash(basedir) : lastpart(basedir));
			strbuf_puts(files, gen_href_end());
			strbuf_puts_nl(files, dir_title_end);
			strbuf_puts_nl(files, "<ul>");
		}
	}
	while ((path = getpath()) != NULL) {
		const char *p, *local = localpath(path, basedir);

		/*
		 * Path is outside of basedir.
		 */
		if (local == NULL) {
			ungetpath();	/* read again by upper level print_directory(). */
			break;
		}
		/*
		 * Path is inside of basedir.
		 */
		else {
			char *slash = strchr(local, '/');

			if (table_flist && flist_items++ % flist_fields == 0)
				PUT(fline_begin);
			/*
			 * Print directory.
			 */
			if (slash) {
				int baselen = strlen(basedir);
				char *q, *last = basedir + baselen;
				int subcount;

				if (baselen + 1 + (slash - local)  > MAXPATHLEN) {
					fprintf(stderr, "Too long path name.\n");
					exit(1);
				}
				/*
				 * Append new directory to the basedir.
				 */
				p = local;
				q = last;
				*q++ = '/';
				while (p < slash)
					*q++ = *p++;
				*q = '\0';
				/*
				 * print tree for this directory.
				 */
				ungetpath();	/* read again by lower level print_directory(). */
				subcount = print_directory(level + 1, basedir);
				PUT(print_directory_name(level, basedir, subcount));
				count += subcount;
				/*
				 * Shrink the basedir.
				 */
				*last = '\0';
			}
			/*
			 * Print file.
			 */
			else {
				const char *file_name = print_file_name(level, path);

				if (tree_view) {
					int size = filesize(path);
					char *target = (Fflag) ? "mains" : "_top";
					char tips[80];

					if (size > 1)
						snprintf(tips, sizeof(tips), "%s bytes", insert_comma(size));
					else
						snprintf(tips, sizeof(tips), "%s byte", insert_comma(size));
					strbuf_sprintf(files, "%s%s%s%s%s\n",
						file_begin,
						gen_href_begin_with_title_target(SRCS, path2fid(path), HTML, NULL, tips, target),
						full_path ? removedotslash(path) : lastpart(path),
						gen_href_end(),
						file_end);
				}
				PUT(file_name);
				if (filemap_file)
					fprintf(FILEMAP, "%s\t%s/%s.%s\n", removedotslash(path), SRCS, path2fid(path), HTML);
				count++;
			}
			if (table_flist && flist_items % flist_fields == 0)
				PUT(fline_end);
		}
	}
	if (flist_items % flist_fields != 0)
		PUT(fline_end);
	if (level > 0) {
		print_directory_footer(op, level, basedir);
		close_file(fileop);
		if (tree_view) {
			strbuf_puts_nl(files, "</ul>");
			strbuf_puts_nl(files, dir_end);
		}
	}
	html_count++;
	return count;
}