示例#1
0
/* Call with mutex locked!  */
static void profile_free_file_data(prf_data_t data)
{
    scan_shared_trees_locked();
    if (data->flags & PROFILE_FILE_SHARED) {
	/* Remove from linked list.  */
	if (g_shared_trees == data)
	    g_shared_trees = data->next;
	else {
	    prf_data_t prev, next;
	    prev = g_shared_trees;
	    next = prev->next;
	    while (next) {
		if (next == data) {
		    prev->next = next->next;
		    break;
		}
		prev = next;
		next = next->next;
	    }
	}
    }
    if (data->root)
	profile_free_node(data->root);
    if (data->comment)
	free(data->comment);
    data->magic = 0;
    k5_mutex_destroy(&data->lock);
    free(data);
    scan_shared_trees_locked();
}
示例#2
0
文件: profile.c 项目: ffainelli/cecd
void profile_free_file(prf_file_t prf)
{
    if (prf->root)
	profile_free_node(prf->root);
    free(prf->filespec);
    free(prf);
}
示例#3
0
文件: prof_parse.c 项目: PADL/krb5
errcode_t profile_process_directory(const char *dirname,
                                    struct profile_node **root)
{
    errcode_t retval;
    struct profile_node *node;

    *root = NULL;
    retval = profile_create_node("(root)", 0, &node);
    if (retval)
        return retval;
    retval = parse_include_dir(dirname, node);
    if (retval) {
        profile_free_node(node);
        return retval;
    }
    *root = node;
    return 0;
}
示例#4
0
文件: prof_parse.c 项目: PADL/krb5
errcode_t profile_parse_file(FILE *f, struct profile_node **root,
                             char **ret_modspec)
{
    struct parse_state state;
    errcode_t retval;

    *root = NULL;

    /* Initialize parsing state with a new root node. */
    state.state = STATE_INIT_COMMENT;
    state.group_level = 0;
    state.current_section = NULL;
    retval = profile_create_node("(root)", 0, &state.root_section);
    if (retval)
        return retval;

    retval = parse_file(f, &state, ret_modspec);
    if (retval) {
        profile_free_node(state.root_section);
        return retval;
    }
    *root = state.root_section;
    return 0;
}
示例#5
0
errcode_t profile_update_file_data(prf_data_t data)
{
	errcode_t retval;
#ifdef HAVE_STAT
	struct stat st;
	unsigned long frac;
	time_t now;
#endif
	FILE *f;

	retval = k5_mutex_lock(&data->lock);
	if (retval)
	    return retval;

#ifdef HAVE_STAT
	now = time(0);
	if (now == data->last_stat && data->root != NULL) {
	    k5_mutex_unlock(&data->lock);
	    return 0;
	}
	if (stat(data->filespec, &st)) {
	    retval = errno;
	    k5_mutex_unlock(&data->lock);
	    return retval;
	}
	data->last_stat = now;
#if defined HAVE_STRUCT_STAT_ST_MTIMENSEC
	frac = st.st_mtimensec;
#elif defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
	frac = st.st_mtimespec.tv_nsec;
#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
	frac = st.st_mtim.tv_nsec;
#else
	frac = 0;
#endif
	if (st.st_mtime == data->timestamp
	    && frac == data->frac_ts
	    && data->root != NULL) {
	    k5_mutex_unlock(&data->lock);
	    return 0;
	}
	if (data->root) {
		profile_free_node(data->root);
		data->root = 0;
	}
	if (data->comment) {
		free(data->comment);
		data->comment = 0;
	}
#else
	/*
	 * If we don't have the stat() call, assume that our in-core
	 * memory image is correct.  That is, we won't reread the
	 * profile file if it changes.
	 */
	if (data->root) {
	    k5_mutex_unlock(&data->lock);
	    return 0;
	}
#endif
	errno = 0;
	f = fopen(data->filespec, "r");
	if (f == NULL) {
		retval = errno;
		k5_mutex_unlock(&data->lock);
		if (retval == 0)
			retval = ENOENT;
		return retval;
	}
	set_cloexec_file(f);
	data->upd_serial++;
	data->flags &= PROFILE_FILE_SHARED;  /* FIXME same as '=' operator */
	retval = profile_parse_file(f, &data->root);
	fclose(f);
	if (retval) {
	    k5_mutex_unlock(&data->lock);
	    return retval;
	}
	assert(data->root != NULL);
#ifdef HAVE_STAT
	data->timestamp = st.st_mtime;
	data->frac_ts = frac;
#endif
	k5_mutex_unlock(&data->lock);
	return 0;
}
errcode_t profile_parse_file(FILE *f, struct profile_node **root)
{
#define BUF_SIZE        2048
    char *bptr;
    errcode_t retval;
    struct parse_state state;

    bptr = malloc (BUF_SIZE);
    if (!bptr)
        return ENOMEM;

    retval = parse_init_state(&state);
    if (retval) {
        free (bptr);
        return retval;
    }
    while (!feof(f)) {
        if (fgets(bptr, BUF_SIZE, f) == NULL)
            break;
#ifndef PROFILE_SUPPORTS_FOREIGN_NEWLINES
        retval = parse_line(bptr, &state);
        if (retval) {
            profile_free_node(state.root_section);
            free (bptr);
            return retval;
        }
#else
        {
            char *p, *end;

            if (strlen(bptr) >= BUF_SIZE - 1) {
                /* The string may have foreign newlines and
                   gotten chopped off on a non-newline
                   boundary.  Seek backwards to the last known
                   newline.  */
                long offset;
                char *c = bptr + strlen (bptr);
                for (offset = 0; offset > -BUF_SIZE; offset--) {
                    if (*c == '\r' || *c == '\n') {
                        *c = '\0';
                        fseek (f, offset, SEEK_CUR);
                        break;
                    }
                    c--;
                }
            }

            /* First change all newlines to \n */
            for (p = bptr; *p != '\0'; p++) {
                if (*p == '\r')
                    *p = '\n';
            }
            /* Then parse all lines */
            p = bptr;
            end = bptr + strlen (bptr);
            while (p < end) {
                char* newline;
                char* newp;

                newline = strchr (p, '\n');
                if (newline != NULL)
                    *newline = '\0';

                /* parse_line modifies contents of p */
                newp = p + strlen (p) + 1;
                retval = parse_line (p, &state);
                if (retval) {
                    profile_free_node(state.root_section);
                    free (bptr);
                    return retval;
                }

                p = newp;
            }
        }
#endif
    }
    *root = state.root_section;

    free (bptr);
    return 0;
}
示例#7
0
文件: profile.c 项目: ffainelli/cecd
/*
 * This function sets the value of the pseudo file "<default>".  If
 * the file "<default>" had previously been passed to profile_init(),
 * then def_string parameter will be parsed and used as the profile
 * information for the "<default>" file.
 */
long profile_set_default(profile_t profile, const char *def_string)
{
	struct parse_state	state;
	prf_file_t		prf;
	long		retval;
	const char		*in;
	char			*line, *p, *end;
	int			line_size, len;

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

	for (prf = profile->first_file; prf; prf = prf->next) {
		if (strcmp(prf->filespec, default_filename) == 0)
			break;
	}
	if (!prf)
		return 0;

	if (prf->root) {
		profile_free_node(prf->root);
		prf->root = 0;
	}

	memset(&state, 0, sizeof(struct parse_state));
	retval = profile_create_node("(root)", 0, &state.root_section);
	if (retval)
		return retval;

	line = 0;
	line_size = 0;
	in = def_string;
	while (*in) {
		end = strchr(in, '\n');
		len = end ? (end - in) : (int) strlen(in);
		if (len >= line_size) {
			line_size = len+1;
			p = realloc(line, line_size);
			if (!p) {
				retval = ENOMEM;
				goto errout;
			}
			line = p;
		}
		memcpy(line, in, len);
		line[len] = 0;
		retval = parse_line(line, &state);
		if (retval) {
		errout:
			if (syntax_err_cb)
				(syntax_err_cb)(prf->filespec, retval,
						state.line_num);
			free(line);
			if (prf->root)
				profile_free_node(prf->root);
			return retval;
		}
		if (!end)
			break;
		in = end+1;
	}
	prf->root = state.root_section;
	free(line);

	return 0;
}