1/* Copyright (C) 2005 Red Hat, Inc. */
2
3struct semanage_bool;
4struct semanage_bool_key;
5typedef struct semanage_bool record_t;
6typedef struct semanage_bool_key record_key_t;
7#define DBASE_RECORD_DEFINED
8
9struct dbase_file;
10typedef struct dbase_file dbase_t;
11#define DBASE_DEFINED
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <ctype.h>
16#include <string.h>
17#include <semanage/handle.h>
18#include "boolean_internal.h"
19#include "database_file.h"
20#include "parse_utils.h"
21#include "debug.h"
22
23static int bool_print(semanage_handle_t * handle,
24		      semanage_bool_t * boolean, FILE * str)
25{
26
27	const char *name = semanage_bool_get_name(boolean);
28	int value = semanage_bool_get_value(boolean);
29
30	if (fprintf(str, "%s=%d\n", name, value) < 0) {
31		ERR(handle, "could not print boolean %s to stream", name);
32		return STATUS_ERR;
33	}
34
35	return STATUS_SUCCESS;
36}
37
38static int bool_parse(semanage_handle_t * handle,
39		      parse_info_t * info, semanage_bool_t * boolean)
40{
41
42	int value = 0;
43	char *str = NULL;
44
45	if (parse_skip_space(handle, info) < 0)
46		goto err;
47	if (!info->ptr)
48		goto last;
49
50	/* Extract name */
51	if (parse_fetch_string(handle, info, &str, '=') < 0)
52		goto err;
53
54	if (semanage_bool_set_name(handle, boolean, str) < 0)
55		goto err;
56	free(str);
57	str = NULL;
58
59	/* Assert = */
60	if (parse_skip_space(handle, info) < 0)
61		goto err;
62	if (parse_assert_ch(handle, info, '=') < 0)
63		goto err;
64
65	/* Extract value */
66	if (parse_skip_space(handle, info) < 0)
67		goto err;
68	if (parse_optional_str(info, "true") != STATUS_NODATA)
69		value = 1;
70	else if (parse_optional_str(info, "TRUE") != STATUS_NODATA)
71		value = 1;
72	else if (parse_optional_str(info, "false") != STATUS_NODATA)
73		value = 0;
74	else if (parse_optional_str(info, "FALSE") != STATUS_NODATA)
75		value = 0;
76	else if (parse_fetch_int(handle, info, &value, ' ') < 0)
77		goto err;
78
79	if (value != 0 && value != 1) {
80		ERR(handle, "invalid boolean value for \"%s\": %u "
81		    "(%s: %u)\n%s", semanage_bool_get_name(boolean),
82		    value, info->filename, info->lineno, info->orig_line);
83		goto err;
84	}
85	semanage_bool_set_value(boolean, value);
86
87	if (parse_assert_space(handle, info) < 0)
88		goto err;
89
90	return STATUS_SUCCESS;
91
92      last:
93	parse_dispose_line(info);
94	return STATUS_NODATA;
95
96      err:
97	ERR(handle, "could not parse boolean record");
98	free(str);
99	parse_dispose_line(info);
100	return STATUS_ERR;
101}
102
103/* BOOL RECORD: FILE extension: method table */
104record_file_table_t SEMANAGE_BOOL_FILE_RTABLE = {
105	.parse = bool_parse,
106	.print = bool_print,
107};
108
109int bool_file_dbase_init(semanage_handle_t * handle,
110			 const char *path_ro,
111			 const char *path_rw,
112			 dbase_config_t * dconfig)
113{
114
115	if (dbase_file_init(handle,
116			    path_ro,
117			    path_rw,
118			    &SEMANAGE_BOOL_RTABLE,
119			    &SEMANAGE_BOOL_FILE_RTABLE, &dconfig->dbase) < 0)
120		return STATUS_ERR;
121
122	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
123	return STATUS_SUCCESS;
124}
125
126void bool_file_dbase_release(dbase_config_t * dconfig)
127{
128
129	dbase_file_release(dconfig->dbase);
130}
131