Esempio n. 1
0
/* to track processes. */
int
start_activity(
	int (details)(samrthread_t *, char **),
	int (destroy)(samrthread_t *),
	activitytype_t type,
	argbuf_t   *args,
	char  **jobidp)
{
	samrthread_t *samtp;
	char jobstr[BUFFSIZ];

	/* set up the pthread attributes to be used hereafter */
	pthread_once(&samr_once_control, samr_once);

	/* Create samrthread_t structure */

	samtp = mallocer(sizeof (samrthread_t));
	if (samtp == NULL)
		return (-1);

	/* Initialize */
	samtp->start = time(NULL); 	/* Start time */
	samtp->pid = 0;
	samtp->tid = 0;
	samtp->type = type;		/* specified by caller */
	samtp->details = details;
	samtp->destroy = destroy;
	samtp->args = args;
	samtp->next = NULL;
	samtp->prev = NULL;

	/* Link structure into active list */
	pthread_mutex_lock(samrlock);	/* ++ LOCK */
	samrjobnum++;			/* ++ Allocate a jobid */
	snprintf(jobstr, BUFFSIZ, "%d", samrjobnum); /* ++ */
	samtp->jobid = copystr(jobstr);	/* Keep copy of ascii string */

	/*
	 * copy the jobid prior to insertion into list so if copy fails
	 * it is easier to cleanup
	 */
	*jobidp = copystr(jobstr);

	if (samtp->jobid == NULL || *jobidp == NULL) {
		if (*jobidp) {
			free(*jobidp);
			*jobidp = NULL;
		}
		if (samtp->jobid) {
			free(samtp->jobid);
		}
		free(samtp);

		/* caller is responsible for freeing any malloced args */

		pthread_mutex_unlock(samrlock);	/* ++ UNLOCK */
		return (-1);
	}

	if (samrtlist == NULL) {
		samrtlist = samtp;
	} else {
		/* Insert structure into list */
		samtp->next = samrtlist;
		samrtlist->prev = samtp;
		samrtlist = samtp;
	}
	pthread_mutex_unlock(samrlock);	/* ++ UNLOCK */

	return (0);
}
Esempio n. 2
0
/*
 * Shell interpreter image activator. A interpreter name beginning
 *	at imgp->args->begin_argv is the minimal successful exit requirement.
 */
int
exec_shell_imgact(struct image_params *imgp)
{
	const char *image_header = imgp->image_header;
	const char *ihp;
	size_t length, offset;
	int error;

	/* a shell script? */
	if (((const short *) image_header)[0] != SHELLMAGIC)
		return(-1);

	/*
	 * Don't allow a shell script to be the shell for a shell
	 *	script. :-)
	 */
	if (imgp->interpreted)
		return(ENOEXEC);

	imgp->interpreted = 1;

	/*
	 * Figure out the number of bytes that need to be reserved in the
	 * argument string to copy the contents of the interpreter's command
	 * line into the argument string.
	 */
	ihp = &image_header[2];
	offset = 0;
	while (ihp < &image_header[PAGE_SIZE]) {
		/* Skip any whitespace */
		if (*ihp == ' ' || *ihp == '\t') {
			++ihp;
			continue;
		}

		/* End of line? */
		if (*ihp == '\n' || *ihp == '#' || *ihp == '\0')
			break;

		/* Found a token */
		do {
			++offset;
			++ihp;
		} while (ihp < &image_header[PAGE_SIZE] &&
			 *ihp != ' ' && *ihp != '\t' && 
			 *ihp != '\n' && *ihp != '#' && *ihp != '\0');

		/* Take into account the \0 that will terminate the token */
		++offset;
	}

	/* If the script gives a null line as the interpreter, we bail */
	if (offset == 0)
		return (ENOEXEC);

	/* It should not be possible for offset to exceed PAGE_SIZE */
	KKASSERT(offset <= PAGE_SIZE);

	/* Check that we aren't too big */
	if (ihp == &image_header[PAGE_SIZE])
		return (ENAMETOOLONG);

	/*
	 * The full path name of the original script file must be tagged
	 * onto the end, adjust the offset to deal with it.  
	 *
	 * The original argv0 is being replaced, set 'length' to the number
	 * of bytes being removed.  So 'offset' is the number of bytes being
	 * added and 'length' is the number of bytes being removed.
	 */
	offset += strlen(imgp->args->fname) + 1;	/* add fname */
	length = strlen(imgp->args->begin_argv) + 1;	/* bytes to delete */

	if (offset - length > imgp->args->space)
		return (E2BIG);

	bcopy(imgp->args->begin_argv + length, imgp->args->begin_argv + offset,
		imgp->args->endp - (imgp->args->begin_argv + length));

	offset -= length;		/* calculate actual adjustment */
	imgp->args->begin_envv += offset;
	imgp->args->endp += offset;
	imgp->args->space -= offset;
	/* decr argc remove old argv[0], incr argc for fname add, net 0 */

	/*
	 * Loop through the interpreter name yet again, copying as
	 * we go.
	 */
	ihp = &image_header[2];
	offset = 0;
	while (ihp < &image_header[PAGE_SIZE]) {
		/* Skip whitespace */
		if (*ihp == ' ' || *ihp == '\t') {
			++ihp;
			continue;
		}

		/* End of line? */
		if (*ihp == '\n' || *ihp == '#' || *ihp == '\0')
			break;

		/* Found a token, copy it */
		do {
			imgp->args->begin_argv[offset] = *ihp;
			++ihp;
			++offset;
		} while (ihp < &image_header[PAGE_SIZE] &&
			 *ihp != ' ' && *ihp != '\t' && 
			 *ihp != '\n' && *ihp != '#' && *ihp != '\0');

		/* And terminate the argument */
		imgp->args->begin_argv[offset] = '\0';
		imgp->args->argc++;
		++offset;
	}

	/*
	 * Finally, add the filename onto the end for the interpreter to
	 * use and copy the interpreter's name to imgp->interpreter_name
	 * for exec to use.
	 */
	error = copystr(imgp->args->fname, imgp->args->buf + offset,
			imgp->args->space, &length);

	if (error == 0) {
		error = copystr(imgp->args->begin_argv, imgp->interpreter_name,
				MAXSHELLCMDLEN, &length);
	}
	return (error);
}
Esempio n. 3
0
int
list_dir(
	ctx_t *c, int maxentries, char *filepath,
	char *restrictions, sqm_lst_t **direntries) /* ARGSUSED */
{
	int rval = 0;
	DIR *curdir;		/* Variable for directory system calls */
	struct dirent64 *entry;	/* Pointer to a directory entry */
	struct dirent64 *entryp;
	struct stat64 sout;
	restrict_t filter = {0};
	char *data;		/* Pointer to data item to add to list */
	char fullpath[MAXPATHLEN];

	/* Set up wildcard restrictions */
	rval = set_restrict(restrictions, &filter);
	if (rval) {
		return (rval);
	}

	curdir = opendir(filepath); /* Set up to ask for directory entries */
	if (curdir == NULL) {
		return (samrerr(SE_NOSUCHPATH, filepath));
	}

	*direntries = lst_create(); /* Return results in this list */
	if (*direntries == NULL) {
		closedir(curdir);
		return (-1);	/* If allocation failed, samerr is set */
	}

	entry = mallocer(sizeof (struct dirent64) + MAXPATHLEN + 1);
	if (entry == NULL) {
		closedir(curdir);
		lst_free(*direntries);
		*direntries = NULL;
		return (-1);
	}

	/* Walk through directory entries */
	while ((rval = readdir64_r(curdir, entry, &entryp)) == 0) {
		if (entryp == NULL) {
			break;
		}

		if ((strcmp(entry->d_name, ".") == 0) ||
		    (strcmp(entry->d_name, "..") == 0)) {
			continue;
		}
		/* Create full pathname and get stat info */
		snprintf(
		    fullpath, MAXPATHLEN, "%s/%s", filepath,
		    entry->d_name);

		if (stat64(fullpath, &sout) != 0) {
			continue; /* Ignore file which can't be stat'ed */
		}

		if (check_restrict_stat(entry->d_name, &sout, &filter))
			continue; /* Not this entry */

		data = copystr(entry->d_name); /* Copy data to allocated mem */
		if (data == NULL) {
			rval = -1;
			break;	/* samerr already set */
		}
		lst_append(*direntries, data);
		if ((*direntries)->length >= maxentries)
			break;	/* Keep list to designated limits */
	}
	free(entry);

	if (rval) {
		lst_free_deep(*direntries); /* On failure, don't return list */
		*direntries = NULL;
	} else {
		lst_qsort(*direntries, node_cmp);
	}
	closedir(curdir);
	return (rval);
}
Esempio n. 4
0
/*
 * Starting at current directory, translate pathname pnp to end.
 * Leave pathname of final component in pnp, return the vnode
 * for the final component in *compvpp, and return the vnode
 * for the parent of the final component in dirvpp.
 *
 * This is the central routine in pathname translation and handles
 * multiple components in pathnames, separating them at /'s.  It also
 * implements mounted file systems and processes symbolic links.
 *
 * vp is the vnode where the directory search should start.
 *
 * Reference counts: vp must be held prior to calling this function.  rootvp
 * should only be held if rootvp != rootdir.
 */
int
lookuppnvp(
	struct pathname *pnp,		/* pathname to lookup */
	struct pathname *rpnp,		/* if non-NULL, return resolved path */
	int flags,			/* follow symlinks */
	vnode_t **dirvpp,		/* ptr for parent vnode */
	vnode_t **compvpp,		/* ptr for entry vnode */
	vnode_t *rootvp,		/* rootvp */
	vnode_t *vp,			/* directory to start search at */
	cred_t *cr)			/* user's credential */
{
	vnode_t *cvp;	/* current component vp */
	char component[MAXNAMELEN];	/* buffer for component (incl null) */
	int error;
	int nlink;
	int lookup_flags;
	struct pathname presrvd; /* case preserved name */
	struct pathname *pp = NULL;
	vnode_t *startvp;
	vnode_t *zonevp = curproc->p_zone->zone_rootvp;		/* zone root */
	int must_be_directory = 0;
	boolean_t retry_with_kcred;
	uint32_t auditing = AU_AUDITING();

	CPU_STATS_ADDQ(CPU, sys, namei, 1);
	nlink = 0;
	cvp = NULL;
	if (rpnp)
		rpnp->pn_pathlen = 0;

	lookup_flags = dirvpp ? LOOKUP_DIR : 0;
	if (flags & FIGNORECASE) {
		lookup_flags |= FIGNORECASE;
		pn_alloc(&presrvd);
		pp = &presrvd;
	}

	if (auditing)
		audit_anchorpath(pnp, vp == rootvp);

	/*
	 * Eliminate any trailing slashes in the pathname.
	 * If there are any, we must follow all symlinks.
	 * Also, we must guarantee that the last component is a directory.
	 */
	if (pn_fixslash(pnp)) {
		flags |= FOLLOW;
		must_be_directory = 1;
	}

	startvp = vp;
next:
	retry_with_kcred = B_FALSE;

	/*
	 * Make sure we have a directory.
	 */
	if (vp->v_type != VDIR) {
		error = ENOTDIR;
		goto bad;
	}

	if (rpnp && VN_CMP(vp, rootvp))
		(void) pn_set(rpnp, "/");

	/*
	 * Process the next component of the pathname.
	 */
	if (error = pn_getcomponent(pnp, component)) {
		goto bad;
	}

	/*
	 * Handle "..": two special cases.
	 * 1. If we're at the root directory (e.g. after chroot or
	 *    zone_enter) then change ".." to "." so we can't get
	 *    out of this subtree.
	 * 2. If this vnode is the root of a mounted file system,
	 *    then replace it with the vnode that was mounted on
	 *    so that we take the ".." in the other file system.
	 */
	if (component[0] == '.' && component[1] == '.' && component[2] == 0) {
checkforroot:
		if (VN_CMP(vp, rootvp) || VN_CMP(vp, zonevp)) {
			component[1] = '\0';
		} else if (vp->v_flag & VROOT) {
			vfs_t *vfsp;
			cvp = vp;

			/*
			 * While we deal with the vfs pointer from the vnode
			 * the filesystem could have been forcefully unmounted
			 * and the vnode's v_vfsp could have been invalidated
			 * by VFS_UNMOUNT. Hence, we cache v_vfsp and use it
			 * with vfs_rlock_wait/vfs_unlock.
			 * It is safe to use the v_vfsp even it is freed by
			 * VFS_UNMOUNT because vfs_rlock_wait/vfs_unlock
			 * do not dereference v_vfsp. It is just used as a
			 * magic cookie.
			 * One more corner case here is the memory getting
			 * reused for another vfs structure. In this case
			 * lookuppnvp's vfs_rlock_wait will succeed, domount's
			 * vfs_lock will fail and domount will bail out with an
			 * error (EBUSY).
			 */
			vfsp = cvp->v_vfsp;

			/*
			 * This lock is used to synchronize
			 * mounts/unmounts and lookups.
			 * Threads doing mounts/unmounts hold the
			 * writers version vfs_lock_wait().
			 */

			vfs_rlock_wait(vfsp);

			/*
			 * If this vnode is on a file system that
			 * has been forcibly unmounted,
			 * we can't proceed. Cancel this operation
			 * and return EIO.
			 *
			 * vfs_vnodecovered is NULL if unmounted.
			 * Currently, nfs uses VFS_UNMOUNTED to
			 * check if it's a forced-umount. Keep the
			 * same checking here as well even though it
			 * may not be needed.
			 */
			if (((vp = cvp->v_vfsp->vfs_vnodecovered) == NULL) ||
			    (cvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)) {
				vfs_unlock(vfsp);
				VN_RELE(cvp);
				if (pp)
					pn_free(pp);
				return (EIO);
			}
			VN_HOLD(vp);
			vfs_unlock(vfsp);
			VN_RELE(cvp);
			cvp = NULL;
			/*
			 * Crossing mount points. For eg: We are doing
			 * a lookup of ".." for file systems root vnode
			 * mounted here, and VOP_LOOKUP() (with covered vnode)
			 * will be on underlying file systems mount point
			 * vnode. Set retry_with_kcred flag as we might end
			 * up doing VOP_LOOKUP() with kcred if required.
			 */
			retry_with_kcred = B_TRUE;
			goto checkforroot;
		}
	}

	/*
	 * LOOKUP_CHECKREAD is a private flag used by vnodetopath() to indicate
	 * that we need to have read permission on every directory in the entire
	 * path.  This is used to ensure that a forward-lookup of a cached value
	 * has the same effect as a reverse-lookup when the cached value cannot
	 * be found.
	 */
	if ((flags & LOOKUP_CHECKREAD) &&
	    (error = VOP_ACCESS(vp, VREAD, 0, cr, NULL)) != 0)
		goto bad;

	/*
	 * Perform a lookup in the current directory.
	 */
	error = VOP_LOOKUP(vp, component, &cvp, pnp, lookup_flags,
	    rootvp, cr, NULL, NULL, pp);

	/*
	 * Retry with kcred - If crossing mount points & error is EACCES.
	 *
	 * If we are crossing mount points here and doing ".." lookup,
	 * VOP_LOOKUP() might fail if the underlying file systems
	 * mount point has no execute permission. In cases like these,
	 * we retry VOP_LOOKUP() by giving as much privilage as possible
	 * by passing kcred credentials.
	 *
	 * In case of hierarchical file systems, passing kcred still may
	 * or may not work.
	 * For eg: UFS FS --> Mount NFS FS --> Again mount UFS on some
	 *			directory inside NFS FS.
	 */
	if ((error == EACCES) && retry_with_kcred)
		error = VOP_LOOKUP(vp, component, &cvp, pnp, lookup_flags,
		    rootvp, zone_kcred(), NULL, NULL, pp);

	if (error) {
		cvp = NULL;
		/*
		 * On error, return hard error if
		 * (a) we're not at the end of the pathname yet, or
		 * (b) the caller didn't want the parent directory, or
		 * (c) we failed for some reason other than a missing entry.
		 */
		if (pn_pathleft(pnp) || dirvpp == NULL || error != ENOENT)
			goto bad;
		if (auditing) {	/* directory access */
			if (error = audit_savepath(pnp, vp, vp, error, cr))
				goto bad_noaudit;
		}

		pn_setlast(pnp);
		/*
		 * We inform the caller that the desired entry must be
		 * a directory by adding a '/' to the component name.
		 */
		if (must_be_directory && (error = pn_addslash(pnp)) != 0)
			goto bad;
		*dirvpp = vp;
		if (compvpp != NULL)
			*compvpp = NULL;
		if (rootvp != rootdir)
			VN_RELE(rootvp);
		if (pp)
			pn_free(pp);
		return (0);
	}

	/*
	 * Traverse mount points.
	 * XXX why don't we need to hold a read lock here (call vn_vfsrlock)?
	 * What prevents a concurrent update to v_vfsmountedhere?
	 * 	Possible answer: if mounting, we might not see the mount
	 *	if it is concurrently coming into existence, but that's
	 *	really not much different from the thread running a bit slower.
	 *	If unmounting, we may get into traverse() when we shouldn't,
	 *	but traverse() will catch this case for us.
	 *	(For this to work, fetching v_vfsmountedhere had better
	 *	be atomic!)
	 */
	if (vn_mountedvfs(cvp) != NULL) {
		if ((error = traverse(&cvp)) != 0)
			goto bad;
	}

	/*
	 * If we hit a symbolic link and there is more path to be
	 * translated or this operation does not wish to apply
	 * to a link, then place the contents of the link at the
	 * front of the remaining pathname.
	 */
	if (cvp->v_type == VLNK && ((flags & FOLLOW) || pn_pathleft(pnp))) {
		struct pathname linkpath;

		if (++nlink > MAXSYMLINKS) {
			error = ELOOP;
			goto bad;
		}
		pn_alloc(&linkpath);
		if (error = pn_getsymlink(cvp, &linkpath, cr)) {
			pn_free(&linkpath);
			goto bad;
		}

		if (auditing)
			audit_symlink(pnp, &linkpath);

		if (pn_pathleft(&linkpath) == 0)
			(void) pn_set(&linkpath, ".");
		error = pn_insert(pnp, &linkpath, strlen(component));
		pn_free(&linkpath);
		if (error)
			goto bad;
		VN_RELE(cvp);
		cvp = NULL;
		if (pnp->pn_pathlen == 0) {
			error = ENOENT;
			goto bad;
		}
		if (pnp->pn_path[0] == '/') {
			do {
				pnp->pn_path++;
				pnp->pn_pathlen--;
			} while (pnp->pn_path[0] == '/');
			VN_RELE(vp);
			vp = rootvp;
			VN_HOLD(vp);
		}
		if (auditing)
			audit_anchorpath(pnp, vp == rootvp);
		if (pn_fixslash(pnp)) {
			flags |= FOLLOW;
			must_be_directory = 1;
		}
		goto next;
	}

	/*
	 * If rpnp is non-NULL, remember the resolved path name therein.
	 * Do not include "." components.  Collapse occurrences of
	 * "previous/..", so long as "previous" is not itself "..".
	 * Exhausting rpnp results in error ENAMETOOLONG.
	 */
	if (rpnp && strcmp(component, ".") != 0) {
		size_t len;

		if (strcmp(component, "..") == 0 &&
		    rpnp->pn_pathlen != 0 &&
		    !((rpnp->pn_pathlen > 2 &&
		    strncmp(rpnp->pn_path+rpnp->pn_pathlen-3, "/..", 3) == 0) ||
		    (rpnp->pn_pathlen == 2 &&
		    strncmp(rpnp->pn_path, "..", 2) == 0))) {
			while (rpnp->pn_pathlen &&
			    rpnp->pn_path[rpnp->pn_pathlen-1] != '/')
				rpnp->pn_pathlen--;
			if (rpnp->pn_pathlen > 1)
				rpnp->pn_pathlen--;
			rpnp->pn_path[rpnp->pn_pathlen] = '\0';
		} else {
			if (rpnp->pn_pathlen != 0 &&
			    rpnp->pn_path[rpnp->pn_pathlen-1] != '/')
				rpnp->pn_path[rpnp->pn_pathlen++] = '/';
			if (flags & FIGNORECASE) {
				/*
				 * Return the case-preserved name
				 * within the resolved path.
				 */
				error = copystr(pp->pn_buf,
				    rpnp->pn_path + rpnp->pn_pathlen,
				    rpnp->pn_bufsize - rpnp->pn_pathlen, &len);
			} else {
				error = copystr(component,
				    rpnp->pn_path + rpnp->pn_pathlen,
				    rpnp->pn_bufsize - rpnp->pn_pathlen, &len);
			}
			if (error)	/* copystr() returns ENAMETOOLONG */
				goto bad;
			rpnp->pn_pathlen += (len - 1);
			ASSERT(rpnp->pn_bufsize > rpnp->pn_pathlen);
		}
	}

	/*
	 * If no more components, return last directory (if wanted) and
	 * last component (if wanted).
	 */
	if (pn_pathleft(pnp) == 0) {
		/*
		 * If there was a trailing slash in the pathname,
		 * make sure the last component is a directory.
		 */
		if (must_be_directory && cvp->v_type != VDIR) {
			error = ENOTDIR;
			goto bad;
		}
		if (dirvpp != NULL) {
			/*
			 * Check that we have the real parent and not
			 * an alias of the last component.
			 */
			if (vn_compare(vp, cvp)) {
				if (auditing)
					(void) audit_savepath(pnp, cvp, vp,
					    EINVAL, cr);
				pn_setlast(pnp);
				VN_RELE(vp);
				VN_RELE(cvp);
				if (rootvp != rootdir)
					VN_RELE(rootvp);
				if (pp)
					pn_free(pp);
				return (EINVAL);
			}
			*dirvpp = vp;
		} else
			VN_RELE(vp);
		if (auditing)
			(void) audit_savepath(pnp, cvp, vp, 0, cr);
		if (pnp->pn_path == pnp->pn_buf)
			(void) pn_set(pnp, ".");
		else
			pn_setlast(pnp);
		if (rpnp) {
			if (VN_CMP(cvp, rootvp))
				(void) pn_set(rpnp, "/");
			else if (rpnp->pn_pathlen == 0)
				(void) pn_set(rpnp, ".");
		}

		if (compvpp != NULL)
			*compvpp = cvp;
		else
			VN_RELE(cvp);
		if (rootvp != rootdir)
			VN_RELE(rootvp);
		if (pp)
			pn_free(pp);
		return (0);
	}

	/*
	 * Skip over slashes from end of last component.
	 */
	while (pnp->pn_path[0] == '/') {
		pnp->pn_path++;
		pnp->pn_pathlen--;
	}

	/*
	 * Searched through another level of directory:
	 * release previous directory handle and save new (result
	 * of lookup) as current directory.
	 */
	VN_RELE(vp);
	vp = cvp;
	cvp = NULL;
	goto next;

bad:
	if (auditing)	/* reached end of path */
		(void) audit_savepath(pnp, cvp, vp, error, cr);
bad_noaudit:
	/*
	 * Error.  Release vnodes and return.
	 */
	if (cvp)
		VN_RELE(cvp);
	/*
	 * If the error was ESTALE and the current directory to look in
	 * was the root for this lookup, the root for a mounted file
	 * system, or the starting directory for lookups, then
	 * return ENOENT instead of ESTALE.  In this case, no recovery
	 * is possible by the higher level.  If ESTALE was returned for
	 * some intermediate directory along the path, then recovery
	 * is potentially possible and retrying from the higher level
	 * will either correct the situation by purging stale cache
	 * entries or eventually get back to the point where no recovery
	 * is possible.
	 */
	if (error == ESTALE &&
	    (VN_CMP(vp, rootvp) || (vp->v_flag & VROOT) || vp == startvp))
		error = ENOENT;
	VN_RELE(vp);
	if (rootvp != rootdir)
		VN_RELE(rootvp);
	if (pp)
		pn_free(pp);
	return (error);
}
Esempio n. 5
0
/*
 * VFS Operations.
 *
 * mount system call
 */
int
ext2fs_mount(struct mount *mp, const char *path, void *data, size_t *data_len)
{
	struct lwp *l = curlwp;
	struct vnode *devvp;
	struct ufs_args *args = data;
	struct ufsmount *ump = NULL;
	struct m_ext2fs *fs;
	size_t size;
	int error = 0, flags, update;
	mode_t accessmode;

	if (*data_len < sizeof *args)
		return EINVAL;

	if (mp->mnt_flag & MNT_GETARGS) {
		ump = VFSTOUFS(mp);
		if (ump == NULL)
			return EIO;
		memset(args, 0, sizeof *args);
		args->fspec = NULL;
		*data_len = sizeof *args;
		return 0;
	}

	update = mp->mnt_flag & MNT_UPDATE;

	/* Check arguments */
	if (args->fspec != NULL) {
		/*
		 * Look up the name and verify that it's sane.
		 */
		error = namei_simple_user(args->fspec,
					NSM_FOLLOW_NOEMULROOT, &devvp);
		if (error != 0)
			return (error);

		if (!update) {
			/*
			 * Be sure this is a valid block device
			 */
			if (devvp->v_type != VBLK)
				error = ENOTBLK;
			else if (bdevsw_lookup(devvp->v_rdev) == NULL)
				error = ENXIO;
		} else {
		        /*
			 * Be sure we're still naming the same device
			 * used for our initial mount
			 */
			ump = VFSTOUFS(mp);
			if (devvp != ump->um_devvp) {
				if (devvp->v_rdev != ump->um_devvp->v_rdev)
					error = EINVAL;
				else {
					vrele(devvp);
					devvp = ump->um_devvp;
					vref(devvp);
				}
			}
		}
	} else {
		if (!update) {
			/* New mounts must have a filename for the device */
			return (EINVAL);
		} else {
			ump = VFSTOUFS(mp);
			devvp = ump->um_devvp;
			vref(devvp);
		}
	}

	/*
	 * If mount by non-root, then verify that user has necessary
	 * permissions on the device.
	 *
	 * Permission to update a mount is checked higher, so here we presume
	 * updating the mount is okay (for example, as far as securelevel goes)
	 * which leaves us with the normal check.
	 */
	if (error == 0) {
		accessmode = VREAD;
		if (update ?
		    (mp->mnt_iflag & IMNT_WANTRDWR) != 0 :
		    (mp->mnt_flag & MNT_RDONLY) == 0)
			accessmode |= VWRITE;
		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
		error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT,
		    KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp,
		    KAUTH_ARG(accessmode));
		VOP_UNLOCK(devvp);
	}

	if (error) {
		vrele(devvp);
		return (error);
	}

	if (!update) {
		int xflags;

		if (mp->mnt_flag & MNT_RDONLY)
			xflags = FREAD;
		else
			xflags = FREAD|FWRITE;
		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
		error = VOP_OPEN(devvp, xflags, FSCRED);
		VOP_UNLOCK(devvp);
		if (error)
			goto fail;
		error = ext2fs_mountfs(devvp, mp);
		if (error) {
			vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
			(void)VOP_CLOSE(devvp, xflags, NOCRED);
			VOP_UNLOCK(devvp);
			goto fail;
		}

		ump = VFSTOUFS(mp);
		fs = ump->um_e2fs;
	} else {
		/*
		 * Update the mount.
		 */

		/*
		 * The initial mount got a reference on this
		 * device, so drop the one obtained via
		 * namei(), above.
		 */
		vrele(devvp);

		ump = VFSTOUFS(mp);
		fs = ump->um_e2fs;
		if (fs->e2fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
			/*
			 * Changing from r/w to r/o
			 */
			flags = WRITECLOSE;
			if (mp->mnt_flag & MNT_FORCE)
				flags |= FORCECLOSE;
			error = ext2fs_flushfiles(mp, flags);
			if (error == 0 &&
			    ext2fs_cgupdate(ump, MNT_WAIT) == 0 &&
			    (fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) {
				fs->e2fs.e2fs_state = E2FS_ISCLEAN;
				(void) ext2fs_sbupdate(ump, MNT_WAIT);
			}
			if (error)
				return (error);
			fs->e2fs_ronly = 1;
		}

		if (mp->mnt_flag & MNT_RELOAD) {
			error = ext2fs_reload(mp, l->l_cred, l);
			if (error)
				return (error);
		}

		if (fs->e2fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) {
			/*
			 * Changing from read-only to read/write
			 */
			fs->e2fs_ronly = 0;
			if (fs->e2fs.e2fs_state == E2FS_ISCLEAN)
				fs->e2fs.e2fs_state = 0;
			else
				fs->e2fs.e2fs_state = E2FS_ERRORS;
			fs->e2fs_fmod = 1;
		}
		if (args->fspec == NULL)
			return 0;
	}

	error = set_statvfs_info(path, UIO_USERSPACE, args->fspec,
	    UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l);
	(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt,
	    sizeof(fs->e2fs_fsmnt) - 1, &size);
	memset(fs->e2fs_fsmnt + size, 0, sizeof(fs->e2fs_fsmnt) - size);
	if (fs->e2fs.e2fs_rev > E2FS_REV0) {
		(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt,
		    sizeof(fs->e2fs.e2fs_fsmnt) - 1, &size);
		memset(fs->e2fs.e2fs_fsmnt, 0,
		    sizeof(fs->e2fs.e2fs_fsmnt) - size);
	}
	if (fs->e2fs_fmod != 0) {	/* XXX */
		fs->e2fs_fmod = 0;
		if (fs->e2fs.e2fs_state == 0)
			fs->e2fs.e2fs_wtime = time_second;
		else
			printf("%s: file system not clean; please fsck(8)\n",
				mp->mnt_stat.f_mntfromname);
		(void) ext2fs_cgupdate(ump, MNT_WAIT);
	}
	return (error);

fail:
	vrele(devvp);
	return (error);
}
Esempio n. 6
0
static struct parseNode *getParseTreeMethod(struct parserState *ps)
{
    int y=getToken(ps);
    struct parseNode *result,*next,*ptr,*type,*arg;
    result=newNode(11);
    result->lineno=ps->lineno;
    if(y==NameToken)
    {
        next=newNode(5);
        next->lineno=ps->lineno;
        result->dat.n=next;
        ptr=next;
        type=newNode(0);
        type->lineno=ps->lineno;
        type->dat.s=copystr(ps->token);
        next->dat.n=type;

        y=getToken(ps);
        if(y==NameToken)
        {
            arg=newNode(0);
            arg->lineno=ps->lineno;
            arg->dat.s=copystr(ps->token);
            type->next=arg;
            y=getToken(ps);
        }
        else
        {
            error("Error! Missing type name or argument type at %d, found %s\n",
                  ps->lineno,ps->token);
            return result;
        }

        while(y!=NoMoreToken && ps->token[0]!=')')
        {
            if(ps->token[0]!=',')
            {
                error("Error! Expected ',' or ';' before %s at %d\n",
                      ps->token,ps->lineno);
                return result;
            }
            y=getToken(ps);
            if(y!=NameToken)
            {
                error("Error! Missing type name or argument type at %d, found %s\n",
                      ps->lineno,ps->token);
                return result;
            }
            next=newNode(5);
            next->lineno=ps->lineno;
            ptr->next=next;
            ptr=next;
            type=newNode(0);
            type->lineno=ps->lineno;
            type->dat.s=copystr(ps->token);
            next->dat.n=type;

            y=getToken(ps);
            if(y==NameToken)
            {
                arg=newNode(0);
                arg->lineno=ps->lineno;
                arg->dat.s=copystr(ps->token);
                type->next=arg;
            }
            else
            {
                error("Error! Missing type name or argument type at %d, found %s\n",
                      ps->lineno,ps->token);
                return result;
            }
            y=getToken(ps);
        }
    }
    y=getToken(ps);
    if(ps->token[0]!='{')
    {
        error("Error! Left bracket { expected at %d, found %s\n"
              ,ps->lineno,ps->token);
        return result;
    }
    result->next=getParseTreeBlock(ps,2);
    result->next->dat.n=repairPTStmt(result->next->dat.n);
    state=getToken(ps);
    return result;
}
Esempio n. 7
0
static struct parseNode *getParseTreeClass(struct parserState *ps)
{
    int y;
    char *name,*baseName=NULL;
    y=getToken(ps);
    if(y==NoMoreToken)
        return NULL;
    if(strcmp(ps->token,"class")!=0)
    {
        error("Error! OOPS only supports classes. Unexpected token %s at %d\n",
              ps->token,ps->lineno);
        return NULL;
    }
    struct parseNode *result,*next,*ptr,*cc;
    result=newNode(1);
    result->lineno=ps->lineno;
    y=getToken(ps);
    if(y==NoMoreToken || y!=NameToken)
    {
        error("Error! Class name expected at line %d\n",ps->lineno);
        return NULL;
    }
    name=copystr(ps->token);

    next=newNode(3);
    next->lineno=ps->lineno;

    cc=newNode(0);
    next->dat.n=cc;
    cc->lineno=ps->lineno;
    cc->dat.s=name;

    result->dat.n=next;
    ptr=next;
    y=getToken(ps);
    if(y!=NoMoreToken && strcmp(ps->token,":")==0)
    {
        y=getToken(ps);
        if(y!=NameToken)
        {
            error("Error! Base class name expected at line %d\n",ps->lineno);
            return result;
        }
        baseName=copystr(ps->token);

        cc=newNode(0);
        cc->lineno=ps->lineno;
        cc->dat.s=baseName;
        next->dat.n->next=cc;

        y=getToken(ps);
    }
    if(y!=NoMoreToken && strcmp(ps->token,"{")==0)
    {
        y=getToken(ps);
        if(y!=NameToken && strcmp(ps->token,"}")!=0)
        {
            error("Error! Method or variable definition expected at %d\n",ps->lineno);
            return result;
        }
        next=getParseTreeVar(ps);
        state=NameToken;
        while(next!=NULL)
        {
            ptr->next=next;
            ptr=next;
            ptr->next=NULL;
            if(errorOccured)
            {
                return result;
            }
            next=getParseTreeVar(ps);
        }

        if(strcmp(ps->token,"}")!=0)
        {
            if(state==NoMoreToken)
                error("Error! Missing right brace } at line %d\n",ps->lineno);
            else if(state!=NameToken)
                error("Error! Method or variable definition expected at %d\n",ps->lineno);
        }
    }
    else
    {
        error("Error! Left brace { expected at line %d\n",ps->lineno);
        return result;
    }
    return result;
}
Esempio n. 8
0
/*-----------------------------------------------------------------------------------*/
static char *
loadtheme(char *str)
{
  return copystr(theme, str, sizeof(theme));
}
Esempio n. 9
0
/*-----------------------------------------------------------------------------------*/
static char *
loadcfs(char *str)
{
  return copystr(cfs, str, sizeof(cfs));
}
Esempio n. 10
0
/*
 * Mount system call
 */
static int
reiserfs_mount(struct mount *mp)
{
	size_t size;
	int error, len;
	accmode_t accmode;
	char *path, *fspec;
	struct vnode *devvp;
	struct vfsoptlist *opts;
	struct reiserfs_mount *rmp;
	struct reiserfs_sb_info *sbi;
	struct nameidata nd, *ndp = &nd;
	struct thread *td;

	td = curthread;
	if (!(mp->mnt_flag & MNT_RDONLY))
		return EROFS;

	/* Get the new options passed to mount */
	opts = mp->mnt_optnew;

	/* `fspath' contains the mount point (eg. /mnt/linux); REQUIRED */
	vfs_getopt(opts, "fspath", (void **)&path, NULL);
	reiserfs_log(LOG_INFO, "mount point is `%s'\n", path);

	/* `from' contains the device name (eg. /dev/ad0s1); REQUIRED */
	fspec = NULL;
	error = vfs_getopt(opts, "from", (void **)&fspec, &len);
	if (!error && fspec[len - 1] != '\0')
		return (EINVAL);
	reiserfs_log(LOG_INFO, "device is `%s'\n", fspec);

	/* Handle MNT_UPDATE (mp->mnt_flag) */
	if (mp->mnt_flag & MNT_UPDATE) {
		/* For now, only NFS export is supported. */
		if (vfs_flagopt(opts, "export", NULL, 0))
			return (0);
	}

	/* Not an update, or updating the name: look up the name
	 * and verify that it refers to a sensible disk device. */
	if (fspec == NULL)
		return (EINVAL);

	NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td);
	if ((error = namei(ndp)) != 0)
		return (error);
	NDFREE(ndp, NDF_ONLY_PNBUF);
	devvp = ndp->ni_vp;

	if (!vn_isdisk(devvp, &error)) {
		vput(devvp);
		return (error);
	}

	/* If mount by non-root, then verify that user has necessary
	 * permissions on the device. */
	accmode = VREAD;
	if ((mp->mnt_flag & MNT_RDONLY) == 0)
		accmode |= VWRITE;
	error = VOP_ACCESS(devvp, accmode, td->td_ucred, td);
	if (error)
		error = priv_check(td, PRIV_VFS_MOUNT_PERM);
	if (error) {
		vput(devvp);
		return (error);
	}

	if ((mp->mnt_flag & MNT_UPDATE) == 0) {
		error = reiserfs_mountfs(devvp, mp, td);
	} else {
		/* TODO Handle MNT_UPDATE */
		vput(devvp);
		return (EOPNOTSUPP);
	}

	if (error) {
		vrele(devvp);
		return (error);
	}

	rmp = VFSTOREISERFS(mp);
	sbi = rmp->rm_reiserfs;

	/*
	 * Note that this strncpy() is ok because of a check at the start
	 * of reiserfs_mount().
	 */
	reiserfs_log(LOG_DEBUG, "prepare statfs data\n");
	(void)copystr(fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
	(void)reiserfs_statfs(mp, &mp->mnt_stat);

	reiserfs_log(LOG_DEBUG, "done\n");
	return (0);
}
Esempio n. 11
0
/*-----------------------------------------------------------------------------------*/
static char *
loaddriver(char *str)
{
  return copystr(driver, str, sizeof(driver));
}
Esempio n. 12
0
static HCACHEFILE* hcachefile_get(TARGET *t)
{
	HCACHEFILE filedata, *file = &filedata;

	SETTINGS *vars;
	const char *hcachename = NULL;
	if ( t->flags & T_FLAG_USEDEPCACHE )
	{
		for ( vars = t->settings; vars; vars = vars->next )
		{
			if ( vars->symbol[0] == 'D'  &&  strcmp( vars->symbol, "DEPCACHE" ) == 0 )
			{
				hcachename = list_value(list_first(vars->value));
				break;
			}
		}
	}

	if ( !hcachename )
	{
		LIST *hcache = var_get( "DEPCACHE" );
		if ( list_first(hcache) )
			hcachename = list_value(list_first(hcache));
	}

	if ( !hcachename )
	{
		hcachename = newstr( "standard" );
	}

	if (lasthcachefile_name == hcachename)
		return lasthcachefile;

	filedata.cachename = hcachename;

	if ( !hcachefilehash ) {
		hcachefilehash = hashinit( sizeof( HCACHEFILE ), "hcachefile" );
	}

	if( !hashcheck( hcachefilehash, (HASHDATA **) &file ) ) {
		if( hashenter( hcachefilehash, (HASHDATA **)&file ) ) {
			char varBuffer[ MAXJPATH ];
			LIST *hcachevar;

			file->cachefilename = 0;
			file->hcachehash = hashinit( sizeof( HCACHEDATA ), "hcache" );
			file->hcachelist = 0;
			file->next = hcachefilelist;
			file->dirty = 0;
			hcachefilelist = file;

			strcpy( varBuffer, "DEPCACHE." );
			strcat( varBuffer, hcachename );

			hcachevar = var_get( varBuffer );
			if( list_first(hcachevar) ) {
				TARGET *t = bindtarget(list_value(list_first(hcachevar)));
				t->boundname = search_using_target_settings( t, t->name, &t->time );

				file->cachefilename = copystr( t->boundname );
				hcache_readfile( file );
			}
		}
	}

	lasthcachefile = file;
	lasthcachefile_name = file->cachename;

	return lasthcachefile;
}
Esempio n. 13
0
/*
 * Function: devfs_kernel_mount
 * Purpose:
 *   Mount devfs at the given mount point from within the kernel.
 */
int
devfs_kernel_mount(char * mntname)
{
	struct mount *mp;
	int error;
	struct nameidata nd;
	struct vnode  * vp;
	vfs_context_t ctx = vfs_context_kernel();
	struct vfstable *vfsp;

	/* Find our vfstable entry */
	for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
		if (!strncmp(vfsp->vfc_name, "devfs", sizeof(vfsp->vfc_name)))
			break;
	
	if (!vfsp) {
		panic("Could not find entry in vfsconf for devfs.\n");
	} 

	/*
	 * Get vnode to be covered
	 */
	NDINIT(&nd, LOOKUP, OP_MOUNT, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
	    CAST_USER_ADDR_T(mntname), ctx);
	if ((error = namei(&nd))) {
	    printf("devfs_kernel_mount: failed to find directory '%s', %d", 
		   mntname, error);
	    return (error);
	}
	nameidone(&nd);
	vp = nd.ni_vp;

	if ((error = VNOP_FSYNC(vp, MNT_WAIT, ctx))) {
	    printf("devfs_kernel_mount: vnop_fsync failed: %d\n", error);
	    vnode_put(vp);
	    return (error);
	}
	if ((error = buf_invalidateblks(vp, BUF_WRITE_DATA, 0, 0))) {
	    printf("devfs_kernel_mount: buf_invalidateblks failed: %d\n", error);
	    vnode_put(vp);
	    return (error);
	}
	if (vnode_isdir(vp) == 0) {
	    printf("devfs_kernel_mount: '%s' is not a directory\n", mntname);
	    vnode_put(vp);
	    return (ENOTDIR);
	}
	if ((vnode_mountedhere(vp))) {
	    vnode_put(vp);
	    return (EBUSY);
	}

	/*
	 * Allocate and initialize the filesystem.
	 */
	MALLOC_ZONE(mp, struct mount *, sizeof(struct mount),
		M_MOUNT, M_WAITOK);
	bzero((char *)mp, sizeof(struct mount));

	/* Initialize the default IO constraints */
	mp->mnt_maxreadcnt = mp->mnt_maxwritecnt = MAXPHYS;
	mp->mnt_segreadcnt = mp->mnt_segwritecnt = 32;
	mp->mnt_ioflags = 0;
	mp->mnt_realrootvp = NULLVP;
	mp->mnt_authcache_ttl = CACHED_LOOKUP_RIGHT_TTL;

	mount_lock_init(mp);
	TAILQ_INIT(&mp->mnt_vnodelist);
	TAILQ_INIT(&mp->mnt_workerqueue);
	TAILQ_INIT(&mp->mnt_newvnodes);

	(void)vfs_busy(mp, LK_NOWAIT);
	mp->mnt_op = &devfs_vfsops;
	mp->mnt_vtable = vfsp;
	mp->mnt_flag = 0;
	mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
	strlcpy(mp->mnt_vfsstat.f_fstypename, vfsp->vfc_name, MFSTYPENAMELEN);
	vp->v_mountedhere = mp;
	mp->mnt_vnodecovered = vp;
	mp->mnt_vfsstat.f_owner = kauth_cred_getuid(kauth_cred_get());
	(void) copystr(mntname, mp->mnt_vfsstat.f_mntonname, MAXPATHLEN - 1, 0);
#if CONFIG_MACF
	mac_mount_label_init(mp);
	mac_mount_label_associate(ctx, mp);
#endif

	error = devfs_mount(mp, NULL, USER_ADDR_NULL, ctx);

	if (error) {
	    printf("devfs_kernel_mount: mount %s failed: %d", mntname, error);
	    mp->mnt_vtable->vfc_refcount--;

	    vfs_unbusy(mp);

	    mount_lock_destroy(mp);
#if CONFIG_MACF
	    mac_mount_label_destroy(mp);
#endif
	    FREE_ZONE(mp, sizeof (struct mount), M_MOUNT);
	    vnode_put(vp);
	    return (error);
	}
	vnode_ref(vp);
	vnode_put(vp);
	vfs_unbusy(mp);
	mount_list_add(mp);
	return (0);
}
Esempio n. 14
0
/*
 * Function to call when a host responds. It would also be appropriate
 * if the responses are asynchronous but the host returns an error on
 * the initial call to handle_request
 *
 * If passed with error_number != 0 the result will be
 * interpreted as an error. Otherwise it is interpreted as a
 * response.
 */
int
host_responded(
char *job_id,
char *host,
int host_num,
int error_number,
char *result) {

	samrthread_t *ptr;
	dispatch_job_t *dj;

	/* result is checked for NULL later */
	if (ISNULL(job_id, host)) {
		Trace(TR_ERR, "failed to find the job: %d %s",
		    samerrno, samerrmsg);
		return (-1);
	}

	Trace(TR_DEBUG, "updating dispatch job %s with response from %s",
	    job_id, host);

	pthread_mutex_lock(samrlock);	/* ++ LOCK samrtlist */
	ptr = find_this_activity(job_id);

	if (ptr == NULL) {
		pthread_mutex_unlock(samrlock);	/* ++ UNLOCK */
		Trace(TR_ERR, "failed to find the job: %d %s",
		    samerrno, samerrmsg);

		return (samrerr(SE_NO_SUCH_ACTIVITY, job_id));
	}

	dj = (dispatch_job_t *)ptr->args->db.job;

	/* Set the error or response for the current host in the job */
	if (host_num < dj->host_count) {
		/* Increment the hosts that have responded */
		dj->hosts_responded++;


		dj->responses[host_num].error = error_number;
		if (error_number == 0) {
			dj->responses[host_num].status = OP_SUCCEEDED;
		} else {
			dj->responses[host_num].status = OP_FAILED;
		}

		/* A result is not mandatory */
		if (result != NULL) {
			dj->responses[host_num].result = copystr(result);
			if (dj->responses[host_num].result == NULL) {
				pthread_mutex_unlock(samrlock);	/* ++ UNLOCK */
				Trace(TR_ERR, "error duplicating result: %d %s",
				    samerrno, samerrmsg);
				return (-1);
			}
		}
	} else {
		pthread_mutex_unlock(samrlock);	/* ++ UNLOCK */
		Trace(TR_ERR, "Host number outside of range");
		setsamerr(SE_INVALID_HOST_ID_IN_RESPONSE);
		return (-1);
	}


	/*
	 * If all hosts have responded, call the post_phase handler to do any
	 * necessary work on this host and set the end time and
	 * overall status.
	 */
	if (dj->hosts_responded == dj->host_count) {
		if (dj->post_phase != NULL) {
			int ret;

			dj->overall_status = DJ_POST_PHASE_PENDING;

			/*
			 * It would be good to do the post phase handling
			 * with the mutex unlocked but it is not currently
			 * safe to do so.
			 */
			ret = dj->post_phase(dj);

			/* Set status */
			if (ret == -1) {
				dj->overall_status = DJ_POST_PHASE_FAILED;
				dj->overall_error_num = samerrno;
				dj->overall_error_msg = copystr(samerrmsg);
			} else {
				dj->overall_status = DJ_POST_PHASE_SUCCEEDED;
			}
			dj->endtime = time(0);

		} else {
			dj->overall_status = DJ_DONE;
			dj->endtime = time(0);
		}
	}


	pthread_mutex_unlock(samrlock);	/* ++ UNLOCK */

	return (0);
}
Esempio n. 15
0
/*
 * Search an alternate path before passing pathname arguments on
 * to system calls. Useful for keeping a separate 'emulation tree'.
 *
 * If cflag is set, we check if an attempt can be made to create
 * the named file, i.e. we check if the directory it should
 * be in exists.
 */
int
emul_find(struct proc *p, caddr_t *sgp, const char *prefix,
    char *path, char **pbuf, int cflag)
{
	struct nameidata	 nd;
	struct nameidata	 ndroot;
	struct vattr		 vat;
	struct vattr		 vatroot;
	int			 error;
	char			*ptr, *buf, *cp;
	const char		*pr;
	size_t			 sz, len;

	buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
	*pbuf = path;

	for (ptr = buf, pr = prefix; (*ptr = *pr) != '\0'; ptr++, pr++)
		continue;

	sz = MAXPATHLEN - (ptr - buf);

	/* 
	 * If sgp is not given then the path is already in kernel space
	 */
	if (sgp == NULL)
		error = copystr(path, ptr, sz, &len);
	else
		error = copyinstr(path, ptr, sz, &len);

	if (error)
		goto bad;

	if (*ptr != '/') {
		error = EINVAL;
		goto bad;
	}

	/*
	 * We know that there is a / somewhere in this pathname.
	 * Search backwards for it, to find the file's parent dir
	 * to see if it exists in the alternate tree. If it does,
	 * and we want to create a file (cflag is set). We don't
	 * need to worry about the root comparison in this case.
	 */

	if (cflag) {
		for (cp = &ptr[len] - 1; *cp != '/'; cp--)
			;
		*cp = '\0';

		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);

		if ((error = namei(&nd)) != 0)
			goto bad;

		*cp = '/';
	} else {
		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);

		if ((error = namei(&nd)) != 0)
			goto bad;

		/*
		 * We now compare the vnode of the emulation root to the one
		 * vnode asked. If they resolve to be the same, then we
		 * ignore the match so that the real root gets used.
		 * This avoids the problem of traversing "../.." to find the
		 * root directory and never finding it, because "/" resolves
		 * to the emulation root directory. This is expensive :-(
		 */
		/* XXX: prototype should have const here for NDINIT */
		NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, prefix, p);

		if ((error = namei(&ndroot)) != 0)
			goto bad2;

		if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0)
			goto bad3;

		if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
		    != 0)
			goto bad3;

		if (vat.va_fsid == vatroot.va_fsid &&
		    vat.va_fileid == vatroot.va_fileid) {
			error = ENOENT;
			goto bad3;
		}
	}
	if (sgp == NULL)
		*pbuf = buf;
	else {
		sz = &ptr[len] - buf;
		*pbuf = stackgap_alloc(sgp, sz + 1);
		if (*pbuf == NULL) {
			error = ENAMETOOLONG;
			goto bad;
		}
		if ((error = copyout(buf, *pbuf, sz)) != 0) {
			*pbuf = path;
			goto bad;
		}
		free(buf, M_TEMP);
	}

	vrele(nd.ni_vp);
	if (!cflag)
		vrele(ndroot.ni_vp);
	return error;

bad3:
	vrele(ndroot.ni_vp);
bad2:
	vrele(nd.ni_vp);
bad:
	free(buf, M_TEMP);
	return error;
}
Esempio n. 16
0
/*-----------------------------------------------------------------------------------*/
static char *
loadscreensaver(char *str)
{
  return copystr(screensaver, str, sizeof(screensaver));
}
Esempio n. 17
0
/*
 * Mount unionfs layer.
 */
static int
unionfs_domount(struct mount *mp)
{
    int		error;
    struct vnode   *lowerrootvp;
    struct vnode   *upperrootvp;
    struct unionfs_mount *ump;
    struct thread *td;
    char           *target;
    char           *tmp;
    char           *ep;
    int		len;
    size_t		done;
    int		below;
    uid_t		uid;
    gid_t		gid;
    u_short		udir;
    u_short		ufile;
    unionfs_copymode copymode;
    unionfs_whitemode whitemode;
    struct componentname fakecn;
    struct nameidata nd, *ndp;
    struct vattr	va;

    UNIONFSDEBUG("unionfs_mount(mp = %p)\n", (void *)mp);

    error = 0;
    below = 0;
    uid = 0;
    gid = 0;
    udir = 0;
    ufile = 0;
    copymode = UNIONFS_TRANSPARENT;	/* default */
    whitemode = UNIONFS_WHITE_ALWAYS;
    ndp = &nd;
    td = curthread;

    if (mp->mnt_flag & MNT_ROOTFS) {
        vfs_mount_error(mp, "Cannot union mount root filesystem");
        return (EOPNOTSUPP);
    }

    /*
     * Update is a no operation.
     */
    if (mp->mnt_flag & MNT_UPDATE) {
        vfs_mount_error(mp, "unionfs does not support mount update");
        return (EOPNOTSUPP);
    }

    /*
     * Get argument
     */
    error = vfs_getopt(mp->mnt_optnew, "target", (void **)&target, &len);
    if (error)
        error = vfs_getopt(mp->mnt_optnew, "from", (void **)&target,
                           &len);
    if (error || target[len - 1] != '\0') {
        vfs_mount_error(mp, "Invalid target");
        return (EINVAL);
    }
    if (vfs_getopt(mp->mnt_optnew, "below", NULL, NULL) == 0)
        below = 1;
    if (vfs_getopt(mp->mnt_optnew, "udir", (void **)&tmp, NULL) == 0) {
        if (tmp != NULL)
            udir = (mode_t)strtol(tmp, &ep, 8);
        if (tmp == NULL || *ep) {
            vfs_mount_error(mp, "Invalid udir");
            return (EINVAL);
        }
        udir &= S_IRWXU | S_IRWXG | S_IRWXO;
    }
    if (vfs_getopt(mp->mnt_optnew, "ufile", (void **)&tmp, NULL) == 0) {
        if (tmp != NULL)
            ufile = (mode_t)strtol(tmp, &ep, 8);
        if (tmp == NULL || *ep) {
            vfs_mount_error(mp, "Invalid ufile");
            return (EINVAL);
        }
        ufile &= S_IRWXU | S_IRWXG | S_IRWXO;
    }
    /* check umask, uid and gid */
    if (udir == 0 && ufile != 0)
        udir = ufile;
    if (ufile == 0 && udir != 0)
        ufile = udir;

    vn_lock(mp->mnt_vnodecovered, LK_SHARED | LK_RETRY);
    error = VOP_GETATTR(mp->mnt_vnodecovered, &va, mp->mnt_cred);
    if (!error) {
        if (udir == 0)
            udir = va.va_mode;
        if (ufile == 0)
            ufile = va.va_mode;
        uid = va.va_uid;
        gid = va.va_gid;
    }
    VOP_UNLOCK(mp->mnt_vnodecovered, 0);
    if (error)
        return (error);

    if (mp->mnt_cred->cr_ruid == 0) {	/* root only */
        if (vfs_getopt(mp->mnt_optnew, "uid", (void **)&tmp,
                       NULL) == 0) {
            if (tmp != NULL)
                uid = (uid_t)strtol(tmp, &ep, 10);
            if (tmp == NULL || *ep) {
                vfs_mount_error(mp, "Invalid uid");
                return (EINVAL);
            }
        }
        if (vfs_getopt(mp->mnt_optnew, "gid", (void **)&tmp,
                       NULL) == 0) {
            if (tmp != NULL)
                gid = (gid_t)strtol(tmp, &ep, 10);
            if (tmp == NULL || *ep) {
                vfs_mount_error(mp, "Invalid gid");
                return (EINVAL);
            }
        }
        if (vfs_getopt(mp->mnt_optnew, "copymode", (void **)&tmp,
                       NULL) == 0) {
            if (tmp == NULL) {
                vfs_mount_error(mp, "Invalid copymode");
                return (EINVAL);
            } else if (strcasecmp(tmp, "traditional") == 0)
                copymode = UNIONFS_TRADITIONAL;
            else if (strcasecmp(tmp, "transparent") == 0)
                copymode = UNIONFS_TRANSPARENT;
            else if (strcasecmp(tmp, "masquerade") == 0)
                copymode = UNIONFS_MASQUERADE;
            else {
                vfs_mount_error(mp, "Invalid copymode");
                return (EINVAL);
            }
        }
        if (vfs_getopt(mp->mnt_optnew, "whiteout", (void **)&tmp,
                       NULL) == 0) {
            if (tmp == NULL) {
                vfs_mount_error(mp, "Invalid whiteout mode");
                return (EINVAL);
            } else if (strcasecmp(tmp, "always") == 0)
                whitemode = UNIONFS_WHITE_ALWAYS;
            else if (strcasecmp(tmp, "whenneeded") == 0)
                whitemode = UNIONFS_WHITE_WHENNEEDED;
            else {
                vfs_mount_error(mp, "Invalid whiteout mode");
                return (EINVAL);
            }
        }
    }
    /* If copymode is UNIONFS_TRADITIONAL, uid/gid is mounted user. */
    if (copymode == UNIONFS_TRADITIONAL) {
        uid = mp->mnt_cred->cr_ruid;
        gid = mp->mnt_cred->cr_rgid;
    }

    UNIONFSDEBUG("unionfs_mount: uid=%d, gid=%d\n", uid, gid);
    UNIONFSDEBUG("unionfs_mount: udir=0%03o, ufile=0%03o\n", udir, ufile);
    UNIONFSDEBUG("unionfs_mount: copymode=%d\n", copymode);

    /*
     * Find upper node
     */
    NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, target, td);
    if ((error = namei(ndp)))
        return (error);

    NDFREE(ndp, NDF_ONLY_PNBUF);

    /* get root vnodes */
    lowerrootvp = mp->mnt_vnodecovered;
    upperrootvp = ndp->ni_vp;

    /* create unionfs_mount */
    ump = (struct unionfs_mount *)malloc(sizeof(struct unionfs_mount),
                                         M_UNIONFSMNT, M_WAITOK | M_ZERO);

    /*
     * Save reference
     */
    if (below) {
        VOP_UNLOCK(upperrootvp, 0);
        vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY);
        ump->um_lowervp = upperrootvp;
        ump->um_uppervp = lowerrootvp;
    } else {
        ump->um_lowervp = lowerrootvp;
        ump->um_uppervp = upperrootvp;
    }
    ump->um_rootvp = NULLVP;
    ump->um_uid = uid;
    ump->um_gid = gid;
    ump->um_udir = udir;
    ump->um_ufile = ufile;
    ump->um_copymode = copymode;
    ump->um_whitemode = whitemode;

    MNT_ILOCK(mp);
    if ((lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE) &&
            (upperrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE))
        mp->mnt_kern_flag |= MNTK_MPSAFE;
    MNT_IUNLOCK(mp);
    mp->mnt_data = ump;

    /*
     * Copy upper layer's RDONLY flag.
     */
    mp->mnt_flag |= ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY;

    /*
     * Check whiteout
     */
    if ((mp->mnt_flag & MNT_RDONLY) == 0) {
        memset(&fakecn, 0, sizeof(fakecn));
        fakecn.cn_nameiop = LOOKUP;
        fakecn.cn_thread = td;
        error = VOP_WHITEOUT(ump->um_uppervp, &fakecn, LOOKUP);
        if (error) {
            if (below) {
                VOP_UNLOCK(ump->um_uppervp, 0);
                vrele(upperrootvp);
            } else
                vput(ump->um_uppervp);
            free(ump, M_UNIONFSMNT);
            mp->mnt_data = NULL;
            return (error);
        }
    }

    /*
     * Unlock the node
     */
    VOP_UNLOCK(ump->um_uppervp, 0);

    /*
     * Get the unionfs root vnode.
     */
    error = unionfs_nodeget(mp, ump->um_uppervp, ump->um_lowervp,
                            NULLVP, &(ump->um_rootvp), NULL, td);
    vrele(upperrootvp);
    if (error) {
        free(ump, M_UNIONFSMNT);
        mp->mnt_data = NULL;
        return (error);
    }

    /*
     * Check mnt_flag
     */
    if ((ump->um_lowervp->v_mount->mnt_flag & MNT_LOCAL) &&
            (ump->um_uppervp->v_mount->mnt_flag & MNT_LOCAL))
        mp->mnt_flag |= MNT_LOCAL;

    /*
     * Get new fsid
     */
    vfs_getnewfsid(mp);

    len = MNAMELEN - 1;
    tmp = mp->mnt_stat.f_mntfromname;
    copystr((below ? "<below>:" : "<above>:"), tmp, len, &done);
    len -= done - 1;
    tmp += done - 1;
    copystr(target, tmp, len, NULL);

    UNIONFSDEBUG("unionfs_mount: from %s, on %s\n",
                 mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);

    return (0);
}
Esempio n. 18
0
/*-----------------------------------------------------------------------------------*/
static char *
ipaddrconf(char *str)
{
  return copystr(ipaddr, str, sizeof(ipaddr));
}
Esempio n. 19
0
static struct parseNode *getParseTreeVar(struct parserState *ps)
{
    struct parseNode *result=NULL,*next,*ptr;
    int y;
    char *name;
    if(ps->token[0]=='}' || ps->token[0]==0)
        return NULL;
    name=copystr(ps->token);
    result=newNode(9);
    result->lineno=ps->lineno;

    next=newNode(0);
    next->lineno=ps->lineno;
    next->dat.s=name;
    result->dat.n=next;
    ptr=next;
    y=getToken(ps);
    if(y!=NameToken && ps->token[0]!='(')
    {
        state=y;
        error("Error! Method or variable name expected at %d, found %s\n"
              ,ps->lineno,ps->token);
        return result;
    }
    if(y==NameToken)
    {
        result->type=7;
        name=copystr(ps->token);
        next=newNode(0);
        next->lineno=ps->lineno;
        next->dat.s=name;
        ptr->next=next;
        ptr=next;
        y=getToken(ps);
    }
    if(ps->token[0]=='(')
    {
        ptr->next=getParseTreeMethod(ps);
    }
    else
    {
        result->type=5;
        while(ps->token[0]==',')
        {
            y=getToken(ps);
            if(y!=NameToken)
            {
                error("Error! Variable name expected at %d, found %s\n"
                      ,ps->lineno,ps->token);
                return result;
            }
            name=copystr(ps->token);
            next=newNode(0);
            next->lineno=ps->lineno;
            next->dat.s=name;
            ptr->next=next;
            ptr=next;
            y=getToken(ps);
        }
        if(ps->token[0]!=';')
        {
            error("Error! Semicolon ; expected at %d\n",ps->lineno);
            return result;
        }
        y=getToken(ps);
        state=y;
    }
    return result;
}
Esempio n. 20
0
/*-----------------------------------------------------------------------------------*/
static char *
netmaskconf(char *str)
{
  return copystr(netmask, str, sizeof(netmask));
}
Esempio n. 21
0
LIST *
var_expand( 
	LIST	*l,
	char	*in,
	char	*end,
	LOL	*lol,
	int	cancopyin )
{
    char out_buf[ MAXSYM ];
    string buf[1];
    string out1[1]; /* Temporary buffer */
    size_t prefix_length;
    char *out;
    char *inp = in;
    char *ov;		/* for temp copy of variable in outbuf */
    int depth;

    if( DEBUG_VAREXP )
        printf( "expand '%.*s'\n", end - in, in );

    /* This gets alot of cases: $(<) and $(>) */

    if( in[0] == '$' && in[1] == '(' && in[3] == ')' && !in[4] )
    {
        switch( in[2] )
        {
        case '1':
        case '<':
            return list_copy( l, lol_get( lol, 0 ) );

        case '2':
        case '>':
            return list_copy( l, lol_get( lol, 1 ) );
        }
    }

    /* Just try simple copy of in to out. */

    while( in < end )
        if( *in++ == '$' && *in == '(' ) 
            goto expand;

    /* No variables expanded - just add copy of input string to list. */

    /* Cancopyin is an optimization: if the input was already a list */
    /* item, we can use the copystr() to put it on the new list. */
    /* Otherwise, we use the slower newstr(). */

    if( cancopyin ) 
    {
        return list_new( l, copystr( inp ) );
    }
    else
    {
        LIST* r;
        string_new( buf );
        string_append_range( buf, inp, end );

        r = list_new( l, newstr( buf->value) );
        string_free( buf );
        return r;
    }

expand:
    string_new( buf );
    string_append_range( buf, inp, in - 1); /* copy the part before '$'. */
    /*
     * Input so far (ignore blanks):
     *
     *  stuff-in-outbuf $(variable) remainder
     *                   ^                   ^
     *                   in                  end
     * Output so far:
     *
     *  stuff-in-outbuf $
     *  ^                ^
     *  out_buf          out
     *
     *
     * We just copied the $ of $(...), so back up one on the output.
     * We now find the matching close paren, copying the variable and
     * modifiers between the $( and ) temporarily into out_buf, so that
     * we can replace :'s with MAGIC_COLON.  This is necessary to avoid
     * being confused by modifier values that are variables containing
     * :'s.  Ugly.
     */

    depth = 1;
    inp = ++in; /* skip over the '(' */

    while( in < end && depth )
    {
        switch( *in++ )
        {
        case '(': depth++; break;
        case ')': depth--; break;
        }
    }

    /*
     * Input so far (ignore blanks):
     *
     *  stuff-in-outbuf $(variable) remainder
     *                    ^        ^         ^
     *                    inp      in        end
     */
    prefix_length = buf->size;
    string_append_range( buf, inp, in - 1 );

    out = buf->value + prefix_length;
    for ( ov = out; ov < buf->value + buf->size; ++ov )
    {
        switch( *ov )
        {
        case ':': *ov = MAGIC_COLON; break;
        case '[': *ov = MAGIC_LEFT; break;
        case ']': *ov = MAGIC_RIGHT; break;
        }
    }

    /*
     * Input so far (ignore blanks):
     *
     *  stuff-in-outbuf $(variable) remainder
     *                              ^        ^
     *                              in       end
     * Output so far:
     *
     *  stuff-in-outbuf variable
     *  ^               ^       ^
     *  out_buf         out     ov
     *
     * Later we will overwrite 'variable' in out_buf, but we'll be
     * done with it by then.  'variable' may be a multi-element list, 
     * so may each value for '$(variable element)', and so may 'remainder'.
     * Thus we produce a product of three lists.
     */

    {
        LIST *variables = 0;
        LIST *remainder = 0;
        LIST *vars;

        /* Recursively expand variable name & rest of input */

        if( out < ov )
            variables = var_expand( L0, out, ov, lol, 0 );
        if( in < end )
            remainder = var_expand( L0, in, end, lol, 0 );

        /* Now produce the result chain */

        /* For each variable name */

        for( vars = variables; vars; vars = list_next( vars ) )
        {
            LIST *value, *evalue = 0;
            char *colon;
            char *bracket;
            string variable[1];
            char *varname;
            int sub1 = 0, sub2 = -1;
            VAR_EDITS edits;

            /* Look for a : modifier in the variable name */
            /* Must copy into varname so we can modify it */

            string_copy( variable, vars->string );
            varname = variable->value;

            if( colon = strchr( varname, MAGIC_COLON ) )
            {
                string_truncate( variable, colon - varname );
                var_edit_parse( colon + 1, &edits );
            }

            /* Look for [x-y] subscripting */
            /* sub1 and sub2 are x and y. */

            if ( bracket = strchr( varname, MAGIC_LEFT ) )
            {
                /*
                ** Make all syntax errors in [] subscripting
                ** result in the same behavior: silenty return an empty
                ** expansion (by setting sub2 = 0). Brute force parsing;
                ** May get moved into yacc someday.
                */

                char *s = bracket + 1;

                string_truncate( variable, bracket - varname );

                do  /* so we can use "break" */
                {
                    /* Allow negative indexes. */
                    if (! isdigit( *s ) && ! ( *s == '-') )
                    {
                        sub2 = 0;
                        break;
                    }
                    sub1 = atoi(s);

                    /* Skip over the first symbol, which is either a digit or dash. */
                    s++;
                    while ( isdigit( *s ) ) s++;

                    if ( *s == MAGIC_RIGHT )
                    {
                        sub2 = sub1;
                        break;
                    }

                    if ( *s != '-')
                    {
                        sub2 = 0;
                        break;
                    }

                    s++;

                    if ( *s == MAGIC_RIGHT )
                    {
                        sub2 = -1;
                        break;
                    }

                    if (! isdigit( *s ) && ! ( *s == '-') )
                    {
                        sub2 = 0;
                        break;
                    }

                    /* First, compute the index of the last element. */
                    sub2 = atoi(s);               
                    s++;
                    while ( isdigit( *s ) ) s++;

                    if ( *s != MAGIC_RIGHT)
                        sub2 = 0;

                } while (0);

                /*
                ** Anything but the end of the string, or the colon
                ** introducing a modifier is a syntax error.
                */

                s++;                
                if (*s && *s != MAGIC_COLON)
                    sub2 = 0;

                *bracket = '\0';
            }

            /* Get variable value, specially handling $(<), $(>), $(n) */
		
            if( varname[0] == '<' && !varname[1] )
                value = lol_get( lol, 0 );
            else if( varname[0] == '>' && !varname[1] )
                value = lol_get( lol, 1 );
            else if( varname[0] >= '1' && varname[0] <= '9' && !varname[1] )
                value = lol_get( lol, varname[0] - '1' );
            else 
                value = var_get( varname );

            /* Handle negitive indexes: part two. */
            {
                int length = list_length( value );

                if (sub1 < 0)
                    sub1 = length + sub1;
                else
                    sub1 -= 1;

                if (sub2 < 0)
                    sub2 = length + 1 + sub2 - sub1;
                else
                    sub2 -= sub1;
                /*
                ** The "sub2 < 0" test handles the semantic error
                ** of sub2 < sub1.
                */
                if ( sub2 < 0 )
                    sub2 = 0;
            }



            /* The fast path: $(x) - just copy the variable value. */
            /* This is only an optimization */

            if( out == out_buf && !bracket && !colon && in == end )
            {
                string_free( variable );
                l = list_copy( l, value );
                continue;
            }

            /* Handle start subscript */

            while( sub1 > 0 && value )
                --sub1, value = list_next( value );

            /* Empty w/ :E=default? */

            if( !value && colon && edits.empty.ptr )
                evalue = value = list_new( L0, newstr( edits.empty.ptr ) );

            /* For each variable value */

            string_new( out1 );
            for( ; value; value = list_next( value ) )
            {
                LIST *rem;
                size_t postfix_start;

                /* Handle end subscript (length actually) */

                if( sub2 >= 0 && --sub2 < 0 )
                    break;

                string_truncate( buf, prefix_length );

                /* Apply : mods, if present */

                if( colon && edits.filemods )
                    var_edit_file( value->string, out1, &edits );
                else
                    string_append( out1, value->string );

                if( colon && ( edits.upshift || edits.downshift || edits.to_slashes || edits.to_windows ) )
                    var_edit_shift( out1, &edits );

                /* Handle :J=joinval */
                /* If we have more values for this var, just */
                /* keep appending them (with the join value) */
                /* rather than creating separate LIST elements. */

                if( colon && edits.join.ptr && 
                    ( list_next( value ) || list_next( vars ) ) )
                {
                    string_append( out1, edits.join.ptr );
                    continue;
                }

                string_append( buf, out1->value );
                string_free( out1 );
                string_new( out1 );

                /* If no remainder, append result to output chain. */

                if( in == end )
                {
                    l = list_new( l, newstr( buf->value ) );
                    continue;
                }

                /* For each remainder, append the complete string */
                /* to the output chain. */
                /* Remember the end of the variable expansion so */
                /* we can just tack on each instance of 'remainder' */

                postfix_start = buf->size;

                for( rem = remainder; rem; rem = list_next( rem ) )
                {
                    string_truncate( buf, postfix_start );
                    string_append( buf, rem->string );
                    l = list_new( l, newstr( buf->value ) );
                }
            }
            string_free( out1 );

            /* Toss used empty */

            if( evalue )
                list_free( evalue );

            string_free( variable );
        }

        /* variables & remainder were gifts from var_expand */
        /* and must be freed */

        if( variables )
            list_free( variables );
        if( remainder)
            list_free( remainder );

        if( DEBUG_VAREXP )
        {
            printf( "expanded to " );
            list_print( l );
            printf( "\n" );
        }

        string_free( buf );
        return l;
    }
}
Esempio n. 22
0
/*-----------------------------------------------------------------------------------*/
static char *
drconf(char *str)
{
  return copystr(gateway, str, sizeof(gateway));
}
Esempio n. 23
0
static int
ufs_extattr_lookup(struct vnode *start_dvp, int lockparent, char *dirname,
    struct vnode **vp, struct proc *p)
{
	struct vop_lookup_args vargs;
	struct componentname cnp;
	struct vnode *target_vp;
	int error;

	bzero(&cnp, sizeof(cnp));
	cnp.cn_nameiop = LOOKUP;
	cnp.cn_flags = ISLASTCN;
	if (lockparent == UE_GETDIR_LOCKPARENT)
		cnp.cn_flags |= LOCKPARENT;
	cnp.cn_proc = p;
	cnp.cn_cred = p->p_ucred;
	MALLOC(cnp.cn_pnbuf, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);

	cnp.cn_nameptr = cnp.cn_pnbuf;
	error = copystr(dirname, cnp.cn_pnbuf, MAXPATHLEN,
	    (size_t *) &cnp.cn_namelen);
	if (error) {
		if (lockparent == UE_GETDIR_LOCKPARENT_DONT) {
			VOP_UNLOCK(start_dvp, 0, p);
		}
		FREE(cnp.cn_pnbuf, M_NAMEI);
		printf("ufs_extattr_lookup: copystr failed\n");
		return (error);
	}
	cnp.cn_namelen--;	/* trim nul termination */
	vargs.a_desc = NULL;
	vargs.a_dvp = start_dvp;
	vargs.a_vpp = &target_vp;
	vargs.a_cnp = &cnp;
	error = ufs_lookup(&vargs);
	FREE(cnp.cn_pnbuf, M_NAMEI);

	if (error) {
		/*
		 * Error condition, may have to release the lock on the parent
		 * if ufs_lookup() didn't.
		 */
		if(lockparent == UE_GETDIR_LOCKPARENT_DONT)
			VOP_UNLOCK(start_dvp, 0, p);

#if 0
	/* -XXX does OpenBSD ufs_lookup always unlock on error? */
		/*
		 * Check that ufs_lookup() didn't release the lock when we
		 * didn't want it to.
		 */
		if ((cnp.cn_flags & PDIRUNLOCK) &&
		    (lockparent == UE_GETDIR_LOCKPARENT))
			panic("ufs_extattr_lookup: lockparent but PDIRUNLOCK");
#endif

		return (error);
	}
/*
	if (target_vp == start_dvp)
		panic("ufs_extattr_lookup: target_vp == start_dvp");
*/

#if 0
	/* PDIRUNLOCK does not exist on OpenBSD */
	if (target_vp != start_dvp &&
	    !(cnp.cn_flags & PDIRUNLOCK) &&
	    (lockparent == UE_GETDIR_LOCKPARENT_DONT))
		panic("ufs_extattr_lookup: !lockparent but !PDIRUNLOCK");

	if ((cnp.cn_flags & PDIRUNLOCK) &&
	    (lockparent == UE_GETDIR_LOCKPARENT))
		panic("ufs_extattr_lookup: lockparent but PDIRUNLOCK");
#endif

	/* printf("ufs_extattr_lookup: success\n"); */
	*vp = target_vp;
	return (0);
}
Esempio n. 24
0
/*-----------------------------------------------------------------------------------*/
static char *
dnsconf(char *str)
{
  return copystr(dnsserver, str, sizeof(dnsserver));
}
Esempio n. 25
0
/*
 * Convert a pathname into a pointer to a vnode.
 *
 * The FOLLOW flag is set when symbolic links are to be followed
 * when they occur at the end of the name translation process.
 * Symbolic links are always followed for all other pathname
 * components other than the last.
 *
 * If the LOCKLEAF flag is set, a locked vnode is returned.
 *
 * The segflg defines whether the name is to be copied from user
 * space or kernel space.
 *
 * Overall outline of namei:
 *
 *	copy in name
 *	get starting directory
 *	while (!done && !error) {
 *		call lookup to search path.
 *		if symbolic link, massage name in buffer and continue
 *	}
 */
int
namei(struct nameidata *ndp)
{
	struct filedesc *fdp;		/* pointer to file descriptor state */
	char *cp;			/* pointer into pathname argument */
	struct vnode *dp;		/* the directory we are searching */
	struct iovec aiov;		/* uio for reading symbolic links */
	struct uio auio;
	int error, linklen;
	struct componentname *cnp = &ndp->ni_cnd;
	struct proc *p = cnp->cn_proc;

	ndp->ni_cnd.cn_cred = ndp->ni_cnd.cn_proc->p_ucred;
#ifdef DIAGNOSTIC
	if (!cnp->cn_cred || !cnp->cn_proc)
		panic ("namei: bad cred/proc");
	if (cnp->cn_nameiop & (~OPMASK))
		panic ("namei: nameiop contaminated with flags");
	if (cnp->cn_flags & OPMASK)
		panic ("namei: flags contaminated with nameiops");
#endif
	fdp = cnp->cn_proc->p_fd;

	/*
	 * Get a buffer for the name to be translated, and copy the
	 * name into the buffer.
	 */
	if ((cnp->cn_flags & HASBUF) == 0)
		cnp->cn_pnbuf = pool_get(&namei_pool, PR_WAITOK);
	if (ndp->ni_segflg == UIO_SYSSPACE)
		error = copystr(ndp->ni_dirp, cnp->cn_pnbuf,
			    MAXPATHLEN, &ndp->ni_pathlen);
	else
		error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf,
			    MAXPATHLEN, &ndp->ni_pathlen);

	/*
	 * Fail on null pathnames
	 */
	if (error == 0 && ndp->ni_pathlen == 1)
		error = ENOENT;

	if (error) {
		pool_put(&namei_pool, cnp->cn_pnbuf);
		ndp->ni_vp = NULL;
		return (error);
	}

#ifdef KTRACE
	if (KTRPOINT(cnp->cn_proc, KTR_NAMEI))
		ktrnamei(cnp->cn_proc, cnp->cn_pnbuf);
#endif
#if NSYSTRACE > 0
	if (ISSET(cnp->cn_proc->p_flag, P_SYSTRACE))
		systrace_namei(ndp);
#endif

	/*
	 *  Strip trailing slashes, as requested
	 */
	if (cnp->cn_flags & STRIPSLASHES) {
		char *end = cnp->cn_pnbuf + ndp->ni_pathlen - 2;

		cp = end;
		while (cp >= cnp->cn_pnbuf && (*cp == '/'))
			cp--;

		/* Still some remaining characters in the buffer */
		if (cp >= cnp->cn_pnbuf) {
			ndp->ni_pathlen -= (end - cp);
			*(cp + 1) = '\0';
		}
	}

	ndp->ni_loopcnt = 0;

	/*
	 * Get starting point for the translation.
	 */
	if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL)
		ndp->ni_rootdir = rootvnode;
	/*
	 * Check if starting from root directory or current directory.
	 */
	if (cnp->cn_pnbuf[0] == '/') {
		dp = ndp->ni_rootdir;
		VREF(dp);
	} else {
		dp = fdp->fd_cdir;
		VREF(dp);
	}
	for (;;) {
		if (!dp->v_mount) {
			/* Give up if the directory is no longer mounted */
			pool_put(&namei_pool, cnp->cn_pnbuf);
			return (ENOENT);
		}
		cnp->cn_nameptr = cnp->cn_pnbuf;
		ndp->ni_startdir = dp;
		if ((error = lookup(ndp)) != 0) {
			pool_put(&namei_pool, cnp->cn_pnbuf);
			return (error);
		}
		/*
		 * Check for symbolic link
		 */
		if ((cnp->cn_flags & ISSYMLINK) == 0) {
			if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0)
				pool_put(&namei_pool, cnp->cn_pnbuf);
			else
				cnp->cn_flags |= HASBUF;
			return (0);
		}
		if ((cnp->cn_flags & LOCKPARENT) && (cnp->cn_flags & ISLASTCN))
			VOP_UNLOCK(ndp->ni_dvp, 0, p);
		if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
			error = ELOOP;
			break;
		}
		if (ndp->ni_pathlen > 1)
			cp = pool_get(&namei_pool, PR_WAITOK);
		else
			cp = cnp->cn_pnbuf;
		aiov.iov_base = cp;
		aiov.iov_len = MAXPATHLEN;
		auio.uio_iov = &aiov;
		auio.uio_iovcnt = 1;
		auio.uio_offset = 0;
		auio.uio_rw = UIO_READ;
		auio.uio_segflg = UIO_SYSSPACE;
		auio.uio_procp = cnp->cn_proc;
		auio.uio_resid = MAXPATHLEN;
		error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred);
		if (error) {
badlink:
			if (ndp->ni_pathlen > 1)
				pool_put(&namei_pool, cp);
			break;
		}
		linklen = MAXPATHLEN - auio.uio_resid;
		if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
			error = ENAMETOOLONG;
			goto badlink;
		}
		if (ndp->ni_pathlen > 1) {
			bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen);
			pool_put(&namei_pool, cnp->cn_pnbuf);
			cnp->cn_pnbuf = cp;
		} else
			cnp->cn_pnbuf[linklen] = '\0';
		ndp->ni_pathlen += linklen;
		vput(ndp->ni_vp);
		dp = ndp->ni_dvp;
		/*
		 * Check if root directory should replace current directory.
		 */
		if (cnp->cn_pnbuf[0] == '/') {
			vrele(dp);
			dp = ndp->ni_rootdir;
			VREF(dp);
		}
	}
	pool_put(&namei_pool, cnp->cn_pnbuf);
	vrele(ndp->ni_dvp);
	vput(ndp->ni_vp);
	ndp->ni_vp = NULL;
	return (error);
}
Esempio n. 26
0
static void processfile(const char *name,
                        int failsilent, int warnonmissing, int printrevisioninfo,
                        int *max_build, int *accum_build,
                        int *max_year, int *max_month, int *max_day,
                        int *ismodified)
{
    char str[MAX_LINELENGTH], str_base[MAX_LINELENGTH];
    char name_base[MAX_LINELENGTH];
    char *p1;
    FILE *fp, *fp_base;
    int build, maj_build;
    int year, month, day;
    int cnt;
    char modchar;
    char *target;

#ifdef DOWNSHIFT_PATHS
    string path;
    char *p;
#endif

    target = copystr( (char*) name );

#ifdef DOWNSHIFT_PATHS
    string_copy( &path, target );
    p = path.value;

    do
    {
        *p = tolower( *p );
#ifdef NT
        /* On NT, we must use backslashes or the file will not be found. */
        if ( *p == '/' )
            *p = PATH_DELIM;
#endif
    }
    while ( *p++ );

    target = path.value;
#endif  /* #ifdef DOWNSHIFT_PATHS */

    /* since we also want to verify whether the file is modified in version
    * control, get the path to the working copy name
    * for every source file "<path>\<filename>, the "working copy" base can
    * be found in "<path>\.svn\text-base\<filename>.svn-base"
    */
    if ((p1 = strrchr(name, PATH_DELIM)) != NULL) {
        ++p1; /* skip directory separator character ('\' in Windows, '/' in Linux) */
        strncpy(name_base, name, (int)(p1 - name));
        name_base[(int)(p1 - name)] = '\0';
    } else {
        name_base[0] = '\0';
        p1 = (char*)name;
    } /* if */
    sprintf(name_base + strlen(name_base), ".svn%ctext-base%c%s.svn-base",
        PATH_DELIM, PATH_DELIM, p1);

    /* first extract the revision keywords */
    fp = fopen(name, "r");
    if (fp == NULL) {
        if (!failsilent)
            fprintf(stderr, "Failed to open input file '%s'\n", name);
        return;
    } /* if */
    fp_base = fopen(name_base, "r");  /* fail silently */
    build = 0;
    maj_build = 0;      /* RCS / CVS */
    year = month = day = 0;

    while (fgets(str, sizeof str, fp) != NULL) {
        if (fp_base == NULL || fgets(str_base, sizeof str_base, fp_base) == NULL)
            str_base[0] = '\0';
        if ((p1 = strstr(str, "$Id:")) != NULL && strchr(p1+1, '$') != NULL) {
            if (sscanf(p1, "$Id: %*s %d %d-%d-%d", &build, &year, &month, &day) < 4
                && sscanf(p1, "$Id: %*s %d %d/%d/%d", &build, &year, &month, &day) < 4)
                if (sscanf(p1, "$Id: %*s %d.%d %d-%d-%d", &maj_build, &build, &year, &month, &day) < 5)
                    sscanf(p1, "$Id: %*s %d.%d %d/%d/%d", &maj_build, &build, &year, &month, &day);
        } else if ((p1 = strstr(str, "$Rev:")) != NULL && strchr(p1+1, '$') != NULL) {
            if (sscanf(p1, "$Rev: %d.%d", &maj_build, &build) < 2) {
                sscanf(p1, "$Rev: %d", &build);
                maj_build = 0;
            } /* if */
        } else if ((p1 = strstr(str, "$Revision:")) != NULL && strchr(p1+1, '$') != NULL) {
            if (sscanf(p1, "$Revision: %d.%d", &maj_build, &build) < 2) {
                /* SvnRev also writes this keyword in its own generated file; read it
                * back for partial updates
                */
                cnt = sscanf(p1, "$Revision: %d%c", &build, &modchar);
                if (cnt == 2 && modchar == 'M' && ismodified != NULL)
                    *ismodified = 1;
                maj_build = 0;
            } /* if */
        } else if ((p1 = strstr(str, "$Date:")) != NULL && strchr(p1+1, '$') != NULL) {
            if (sscanf(p1, "$Date: %d-%d-%d", &year, &month, &day) < 3)
                sscanf(p1, "$Date: %d/%d/%d", &year, &month, &day);
        } else if (ismodified != NULL && *ismodified == 0 && fp_base != NULL) {
            /* no keyword present, compare the lines for equivalence */
            *ismodified = strcmp(str, str_base) != 0;
        } /* if */

        if (maj_build)
            *accum_build += build;            /* RCS / CVS */
        else if (build > *max_build)
            *max_build = build;               /* Subversion */
        if (year > *max_year
            || (year == *max_year && month > *max_month)
            || (year == *max_year && month == *max_month && day > *max_day))
        {
            *max_year = year;
            *max_month = month;
            *max_day = day;
        } /* if */
        if (build > 0 && year > 0 && (fp_base == NULL || ismodified == NULL || *ismodified != 0))
            break;      /* both build # and date found, not comparing or modification
                        * already found => no need to search further */

    } /* while */
    fclose(fp);
    if (fp_base != NULL)
        fclose(fp_base);

    if (build == 0 && warnonmissing)
        fprintf(stderr, "Missing revision info in: %s\n", name);
    else if (printrevisioninfo)
        printf("%d %4d-%02d-%02d %d %s\n", build, year, month, day, *ismodified, name);
}
Esempio n. 27
0
static int
ufs_extattr_lookup(struct vnode *start_dvp, int lockparent, char *dirname,
    struct vnode **vp, struct thread *td)
{
	struct vop_cachedlookup_args vargs;
	struct componentname cnp;
	struct vnode *target_vp;
	int error;

	bzero(&cnp, sizeof(cnp));
	cnp.cn_nameiop = LOOKUP;
	cnp.cn_flags = ISLASTCN;
	if (lockparent == UE_GETDIR_LOCKPARENT)
		cnp.cn_flags |= LOCKPARENT;
	cnp.cn_lkflags = LK_EXCLUSIVE;
	cnp.cn_thread = td;
	cnp.cn_cred = td->td_ucred;
	cnp.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
	cnp.cn_nameptr = cnp.cn_pnbuf;
	error = copystr(dirname, cnp.cn_pnbuf, MAXPATHLEN,
	    (size_t *) &cnp.cn_namelen);
	if (error) {
		if (lockparent == UE_GETDIR_LOCKPARENT_DONT) {
			VOP_UNLOCK(start_dvp, 0);
		}
		uma_zfree(namei_zone, cnp.cn_pnbuf);
		printf("ufs_extattr_lookup: copystr failed\n");
		return (error);
	}
	cnp.cn_namelen--;	/* trim nul termination */
	vargs.a_gen.a_desc = NULL;
	vargs.a_dvp = start_dvp;
	vargs.a_vpp = &target_vp;
	vargs.a_cnp = &cnp;
	error = ufs_lookup(&vargs);
	uma_zfree(namei_zone, cnp.cn_pnbuf);
	if (error) {
		/*
		 * Error condition, may have to release the lock on the parent
		 * if ufs_lookup() didn't.
		 */
		if (lockparent == UE_GETDIR_LOCKPARENT_DONT)
			VOP_UNLOCK(start_dvp, 0);

		/*
		 * Check that ufs_lookup() didn't release the lock when we
		 * didn't want it to.
		 */
		if (lockparent == UE_GETDIR_LOCKPARENT)
			ASSERT_VOP_LOCKED(start_dvp, "ufs_extattr_lookup");

		return (error);
	}
/*
	if (target_vp == start_dvp)
		panic("ufs_extattr_lookup: target_vp == start_dvp");
*/

	if (target_vp != start_dvp && lockparent == UE_GETDIR_LOCKPARENT_DONT)
		VOP_UNLOCK(start_dvp, 0);

	if (lockparent == UE_GETDIR_LOCKPARENT)
		ASSERT_VOP_LOCKED(start_dvp, "ufs_extattr_lookup");

	/* printf("ufs_extattr_lookup: success\n"); */
	*vp = target_vp;
	return (0);
}
Esempio n. 28
0
void initializeTypeArray()
{
  int i;
  dwarf_entry * cur_entry;
  struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
  struct genhashtable * sht=NULL;

  if (rootfile!=NULL) {
    char buf[512];
    char a;
    int fd=open(rootfile,O_RDONLY);
    int offset=0;
    sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
    while(1) {
      if (read(fd,&a,1)>0) {
	if (a!=13&&a!=10)
	  buf[offset++]=a;
      } else
	  break;
      if (offset>0&&(a==13||a==10)) {
	buf[offset++]=0;
	{
	  char *str=copystr(buf);
	  genputtable(sht,str,str);
	}
	offset=0;
      }
    }
  }

  if (arrayfile!=NULL) {
    char buf[512];
    char sizebuf[512];
    char a;
    int fd=open(arrayfile,O_RDONLY);
    int offset=0;
    int readmore=1;
    int state=0;
    arrayt=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
    arraytype=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
    while(readmore) {
      if (read(fd,&a,1)<=0)
        readmore=0;
      if (readmore) {
        if (a==' ') {
          state=1;
          buf[offset]=0;
          offset=0;
        } else if (a!=13&&a!=10) {
          if (state==0)
            buf[offset++]=a;
          else
            sizebuf[offset++]=a;
        }
      }
      if ((state==1)&&offset>0&&(a==13||a==10||!readmore)) {
        state=0;
	sizebuf[offset]=0;
	{
	  char *str=copystr(buf);
	  char *sizestr=copystr(sizebuf);
	  genputtable(arrayt,str,sizestr);
	}
	offset=0;
      }
    }
  }

  /* Assign names */
  for (i = 0; i < dwarf_entry_array_size; i++)
    {
      cur_entry = &dwarf_entry_array[i];
      if (entry_is_type(cur_entry))
        {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
	  int j=0;
	  int offset=0;
	  int value=0;
	  
	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      value++;
	    } else {
	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETTYPE);
	      char *poststr=printname(type,POSTNAME);

	      if (typestr!=NULL)
		value++;
	    }
	  }
        }
    }

  for (i = 0; i < dwarf_entry_array_size; i++)
    {
      cur_entry = &dwarf_entry_array[i];
      if (entry_is_type(cur_entry))
        {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
	  int j=0;
	  int offset=0;
	  int value=0;
	  
	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      value++;
	    } else {
	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETTYPE);
	      char *poststr=printname(type,POSTNAME);

	      if (typestr!=NULL)
		value++;
	    }
	  }

	  if (collection_ptr->name!=NULL) {
	    struct valuepair *vp=NULL;
	    if (gencontains(ght,collection_ptr->name))
	      vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
	    if (vp==NULL||vp->value<value) {
	      if (vp==NULL) {
		vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
		genputtable(ght,collection_ptr->name,vp);
	      }
	      vp->value=value;
	      vp->index=i;
	    }
	  }
        }
    }

  assigntype=1;
  if (sht!=NULL) {
    int repeat=1;
    while(repeat) {
      repeat=0;
      for (i = 0; i < dwarf_entry_array_size; i++) {
	cur_entry = &dwarf_entry_array[i];
	if (entry_is_type(cur_entry)) {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);

	  int j=0;
	  int offset=0;
	  int value=0;

	  if (!gencontains(sht,collection_ptr->name))
	    continue;
	  if (gencontains(ght,collection_ptr->name)) {
	    struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
	    if (vp->index!=i)
	      continue;
	  }

	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
	      dwarf_entry *typeptr=in_ptr->target_ptr;
	      collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
	      if (!gencontains(sht,sub_ptr->name)) {
		repeat=1;
		genputtable(sht,sub_ptr->name,sub_ptr->name);
	      }
	    } else {
	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETJUSTTYPE);
	      if (typestr!=NULL&&!gencontains(sht,typestr)) {
		repeat=1;
		genputtable(sht,typestr,typestr);
	      }
	    }
	  }
	}
      }
    }
  }


  for (i = 0; i < dwarf_entry_array_size; i++)
    {
      cur_entry = &dwarf_entry_array[i];
      if (entry_is_type(cur_entry))
        {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
	  int j=0;
	  int offset=0;
	  if (collection_ptr->name==NULL)
	    continue;
	  if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
	    continue;
	  if (gencontains(ght,collection_ptr->name)) {
	    struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
	    if (vp->index!=i)
	      continue;
	  }
	  j=0;
	  printf("structure %s ",collection_ptr->name);

	  while(j<collection_ptr->num_members&&
		collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
	    inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
	    dwarf_entry *typeptr=in_ptr->target_ptr;
	    collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
	    if (j==0)
	      printf("subclass of ");
	    else
	      printf(", ");
	    printf("%s ",sub_ptr->name);
	    j++;
	  }
	  printf("{ \n");

	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      inherit * inherit_ptr=(inherit *)entry->entry_ptr;
	      if (inherit_ptr->data_member_location>offset) {
		printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
		offset=inherit_ptr->data_member_location;
	      }
	      {
		dwarf_entry *type=inherit_ptr->target_ptr;
		collection_type *c_ptr=(collection_type*)type->entry_ptr;
		offset+=printtype(c_ptr,ght);
	      }
    	    } else {
     	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETTYPE);
	      char *poststr=printname(type,POSTNAME);
	      char *newname=NULL;
	      if (member_ptr->data_member_location>offset) {
		printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
		offset=member_ptr->data_member_location;
	      }
	      offset+=getsize(type);
	      newname=escapestr(name);
              {
                char buf[512];
                char *dtype;
                sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
                if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
                  genputtable(arraytype, copystr(buf), typestr);
                  dtype=deref(typestr);
                  printf("   %s_array * %s%s;\n",dtype,newname,poststr);
                  free(dtype);
                } else
                  printf("   %s %s%s;\n",typestr,newname,poststr);
              }
	      free(newname);
	    }
	  }
	  if (offset<collection_ptr->byte_size)
	    printf("   reserved byte[%ld];\n",collection_ptr->byte_size-offset);
	  printf("}\n\n");
        }
    }
  if (arrayt!=NULL) {
    struct geniterator * gi=gengetiterator(arrayt);
    while(1) {
      char * str=(char *)gennext(gi);
      char *size=NULL;
      char *typestr=NULL;
      if (str==NULL)
        break;

      size=(char *)gengettable(arrayt,str);
      typestr=deref((char *)gengettable(arraytype,str));

      printf("structure %s_array {\n",typestr);
      printf("  %s elem[%s];\n",typestr,size);
      printf("}\n");
      free(typestr);
    }
    genfreeiterator(gi);
  }

}
Esempio n. 29
0
/*
 *  filepath may be either a directory or a fully-qualified path.
 *  if it's fully-qualified, only directory entries that sort alphabetically
 *  after the specified file will be returned.
 *
 *  morefiles will be set if there are more entries left in the directory
 *  after maxentries have been returned.  This is intended to let the caller
 *  know they can continue reading.
 *
 *  Note that the directory may change while we're reading it.  If it does,
 *  files that have been added or removed since we started reading it may
 *  not be accurately reflected.
 */
int
list_directory(
	ctx_t		*c,			/* ARGSUSED */
	int		maxentries,
	char		*listDir,		/* directory to list */
	char		*startFile,		/* if continuing, start here */
	char		*restrictions,
	uint32_t	*morefiles,		/* OUT */
	sqm_lst_t		**direntries)		/* OUT */
{
	int		rval = 0;
	int		st = 0;
	DIR		*curdir; /* Variable for directory system calls */
	dirent64_t	*entry;	/* Pointer to a directory entry */
	dirent64_t	*entryp;
	struct stat64	sout;
	restrict_t	filter = {0};
	char		*data;	/* Pointer to data item to add to list */
	node_t		*node;
	sqm_lst_t		*lstp = NULL;
	char		buf[MAXPATHLEN + 1];
	char		*fname;

	if (ISNULL(listDir, direntries, morefiles)) {
		return (-1);
	}

	*morefiles = 0;

	/* Set up wildcard restrictions */
	rval = set_restrict(restrictions, &filter);
	if (rval) {
		return (rval);
	}

	curdir = opendir(listDir); /* Set up to ask for directory entries */
	if (curdir == NULL) {
		return (samrerr(SE_NOSUCHPATH, listDir));
	}

	*direntries = lst_create(); /* Return results in this list */
	if (*direntries == NULL) {
		closedir(curdir);
		return (-1);	/* If allocation failed, samerr is set */
	}
	lstp = *direntries;

	entry = mallocer(sizeof (struct dirent64) + MAXPATHLEN + 1);
	if (entry == NULL) {
		closedir(curdir);
		lst_free(*direntries);
		*direntries = NULL;
		return (-1);
	}

	/* Walk through directory entries */
	while ((rval = readdir64_r(curdir, entry, &entryp)) == 0) {
		if (entryp == NULL) {
			break;
		}

		fname = (char *)&(entry->d_name[0]);

		if ((strcmp(fname, ".") == 0) ||
		    (strcmp(fname, "..") == 0)) {
			continue;
		}

		/*
		 * If we were given a non-directory, start after
		 * that file alphabetically.
		 */
		if (startFile != NULL) {
			if ((strcmp(fname, startFile)) <= 0) {
				continue;
			}
		}

		/* Create full pathname and get stat info */
		snprintf(buf, sizeof (buf), "%s/%s", listDir, fname);
		if (lstat64(buf, &sout) != 0) {
			continue; /* Ignore file which can't be stat'ed */
		}

		/*
		 * think about ways to avoid a double-stat in when we're
		 * fetching file details
		 */
		if (check_restrict_stat(fname, &sout, &filter)) {
			continue; /* Not this entry */
		}

		/* copy to allocated struct */
		data = copystr(fname);
		if (data == NULL) {
			rval = -1;
			break;	/* samerr already set */
		}

		/*
		 * caller wants all entries for the directory
		 * should there be a top-end limit, to avoid the case where
		 * the directory has millions of entries?
		 */
		if (maxentries <= 0) {
			rval = lst_append(lstp, data);
			if (rval != 0) {
				free(data);
				break;
			}
			continue;
		}

		/*
		 * Directory may have more entries than requested, so pre-sort
		 * the list so we return the first <n> sorted alphabetically.
		 */
		for (node = lstp->head; node != NULL; node = node->next) {

			st = strcmp(data, (char *)(node->data));
			if (st > 0) {
				continue;
			}

			if (st < 0) {
				rval = lst_ins_before(lstp, node, data);
				data = NULL;
			}

			if ((rval != 0) || (st == 0)) {
				free(data);
				data = NULL;
			}
			break;
		}

		/* entry sorts higher than existing entries */
		if (data != NULL) {
			if (lstp->length < maxentries) {
				rval = lst_append(lstp, data);
				if (rval != 0) {
					free(data);
					break;
				}
			} else {
				/* no room for this entry */
				free(data);
				(*morefiles)++;
			}
		}

		/* Keep list to designated limits */
		if (lstp->length > maxentries) {
			/* pop off the last entry */
			lst_remove(lstp, lstp->tail);
			(*morefiles)++;
		}
	}

	closedir(curdir);
	free(entry);

	if (rval) {
		lst_free_deep(*direntries);
		*direntries = NULL;
	} else if (maxentries <= 0) {
		lst_qsort(*direntries, node_cmp);
	}

	return (rval);
}
Esempio n. 30
0
int getattributes(entry_t *entry, int argc, char **argv)
/* Convert state or difference file info into file attributes. */
{
	int i;
	int attr;
#define A_MODE1		0x01	/* Some of these attributes follow the name */
#define A_MODE		0x02
#define	A_OWNER		0x04
#define A_SIZETIME	0x08
#define A_DEV		0x10
#define A_LINK		0x20

	switch (argv[0][0]) {
	case 'd':
		/* Directory. */
		entry->type= F_DIR;
		attr= A_MODE1 | A_OWNER;
		break;
	case 'b':
		/* Block device. */
		entry->type= F_BLK;
		attr= A_MODE1 | A_OWNER | A_DEV;
		break;
	case 'c':
		/* Character device. */
		entry->type= F_CHR;
		attr= A_MODE1 | A_OWNER | A_DEV;
		break;
	case 'p':
		/* Named pipe. */
		entry->type= F_PIPE;
		attr= A_MODE1 | A_OWNER;
		break;
	case '-':
		/* Symlink. */
		entry->type= F_LINK;
		attr= A_LINK;
		break;
	default:
		/* Normal file. */
		entry->type= F_FILE;
		attr= A_MODE | A_OWNER | A_SIZETIME;
	}

	if (attr & (A_MODE | A_MODE1)) {
		entry->mode= strtoul(argv[0] + (attr & A_MODE1), nil, 010);
	}
	i= 1;
	if (attr & A_OWNER) {
		if (i + 2 > argc) return 0;
		entry->uid= strtoul(argv[i++], nil, 10);
		entry->gid= strtoul(argv[i++], nil, 10);
	}
	if (attr & A_SIZETIME) {
		if (i + 2 > argc) return 0;
		entry->size= strtoul(argv[i++], nil, 10);
		entry->mtime= strtoul(argv[i++], nil, 10);
	}
	if (attr & A_DEV) {
		if (i + 1 > argc) return 0;
		entry->rdev= strtoul(argv[i++], nil, 0x10);
	}
	if (attr & A_LINK) {
		if (i + 1 > argc) return 0;
		entry->link= argv[i++];
	}
	entry->linked= entry->lastlink= 0;
	if (i < argc) {
		/* It has a fake inode number, so it is a hard link. */
		static struct links {	/* List of hard links. */
			struct links	*next;
			unsigned long	fake_ino;
			char		*path;
		} *links[1024];
		struct links **plp, *lp;
		unsigned long fake_ino;

		fake_ino= strtoul(argv[i++], nil, 10);

		plp= &links[fake_ino % arraysize(links)];
		while ((lp= *plp) != nil && lp->fake_ino != fake_ino)
			plp= &lp->next;

		if (lp == nil) {
			/* New link. */
			*plp= lp= allocate(nil, sizeof(*lp));
			lp->next= nil;
			lp->fake_ino= fake_ino;
			lp->path= copystr(entry->path);
		} else {
			/* Linked to. */
			entry->link= lp->path;
			entry->linked= 1;
		}

		if (i < argc) {
			if (strcmp(argv[i++], "last") != 0) return 0;

			/* Last hard link of a file. */
			forget(lp->path);
			*plp= lp->next;
			deallocate(lp);
			entry->lastlink= 1;
		}
	}
	if (i != argc) return 0;
	return 1;
}