コード例 #1
0
ファイル: prof_set.c プロジェクト: andreiw/polaris
static errcode_t rw_setup(profile_t profile)
{
   	prf_file_t	file;
	errcode_t	retval = 0;

	if (!profile)
		return PROF_NO_PROFILE;

	if (profile->magic != PROF_MAGIC_PROFILE)
		return PROF_MAGIC_PROFILE;

	file = profile->first_file;

	retval = profile_lock_global();
	if (retval)
	    return retval;

	/* Don't update the file if we've already made modifications */
	if (file->data->flags & PROFILE_FILE_DIRTY) {
	    profile_unlock_global();
	    return 0;
	}

	if ((file->data->flags & PROFILE_FILE_SHARED) != 0) {
	    prf_data_t new_data;
	    new_data = profile_make_prf_data(file->data->filespec);
	    if (new_data == NULL) {
		retval = ENOMEM;
	    } else {
		retval = k5_mutex_init(&new_data->lock);
		if (retval == 0) {
		    new_data->root = NULL;
		    new_data->flags = file->data->flags & ~PROFILE_FILE_SHARED;
		    new_data->timestamp = 0;
		    new_data->upd_serial = file->data->upd_serial;
		}
	    }

	    if (retval != 0) {
		profile_unlock_global();
		free(new_data);
		return retval;
	    }
	    profile_dereference_data_locked(file->data);
	    file->data = new_data;
	}

	profile_unlock_global();
	retval = profile_update_file(file);

	return retval;
}
コード例 #2
0
ファイル: prof_file.c プロジェクト: FarazShaikh/LikewiseSMB2
errcode_t profile_open_file(const_profile_filespec_t filespec,
			    prf_file_t *ret_prof)
{
	prf_file_t	prf;
	errcode_t	retval;
	char		*home_env = 0;
	prf_data_t	data;
	char		*expanded_filename;

	retval = CALL_INIT_FUNCTION(profile_library_initializer);
	if (retval)
		return retval;

	scan_shared_trees_unlocked();

	prf = malloc(sizeof(struct _prf_file_t));
	if (!prf)
		return ENOMEM;
	memset(prf, 0, sizeof(struct _prf_file_t));
	prf->magic = PROF_MAGIC_FILE;

	if (filespec[0] == '~' && filespec[1] == '/') {
		home_env = getenv("HOME");
#ifdef HAVE_PWD_H
		if (home_env == NULL) {
		    uid_t uid;
		    struct passwd *pw, pwx;
		    char pwbuf[BUFSIZ];

		    uid = getuid();
		    if (!k5_getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw)
			&& pw != NULL && pw->pw_dir[0] != 0)
			home_env = pw->pw_dir;
		}
#endif
	}
	if (home_env) {
	    if (asprintf(&expanded_filename, "%s%s", home_env,
			 filespec + 1) < 0)
		expanded_filename = 0;
	} else
	    expanded_filename = strdup(filespec);
	if (expanded_filename == 0) {
	    free(prf);
	    return ENOMEM;
	}

	retval = k5_mutex_lock(&g_shared_trees_mutex);
	if (retval) {
	    free(expanded_filename);
	    free(prf);
	    scan_shared_trees_unlocked();
	    return retval;
	}
	scan_shared_trees_locked();
	for (data = g_shared_trees; data; data = data->next) {
	    if (!strcmp(data->filespec, expanded_filename)
		/* Check that current uid has read access.  */
		&& r_access(data->filespec))
		break;
	}
	if (data) {
	    data->refcount++;
	    (void) k5_mutex_unlock(&g_shared_trees_mutex);
	    retval = profile_update_file_data(data);
	    free(expanded_filename);
	    prf->data = data;
	    *ret_prof = prf;
	    scan_shared_trees_unlocked();
	    return retval;
	}
	(void) k5_mutex_unlock(&g_shared_trees_mutex);
	data = profile_make_prf_data(expanded_filename);
	if (data == NULL) {
	    free(prf);
	    free(expanded_filename);
	    return ENOMEM;
	}
	free(expanded_filename);
	prf->data = data;

	retval = k5_mutex_init(&data->lock);
	if (retval) {
	    free(data);
	    free(prf);
	    return retval;
	}

	retval = profile_update_file(prf);
	if (retval) {
		profile_close_file(prf);
		return retval;
	}

	retval = k5_mutex_lock(&g_shared_trees_mutex);
	if (retval) {
	    profile_close_file(prf);
	    scan_shared_trees_unlocked();
	    return retval;
	}
	scan_shared_trees_locked();
	data->flags |= PROFILE_FILE_SHARED;
	data->next = g_shared_trees;
	g_shared_trees = data;
	scan_shared_trees_locked();
	(void) k5_mutex_unlock(&g_shared_trees_mutex);

	*ret_prof = prf;
	return 0;
}