28 #endif // HAVE_CONFIG_H
44 #define LOG_CATEGORY "libnfc.config"
45 #define LOG_GROUP NFC_LOG_GROUP_CONFIG
47 #ifndef LIBNFC_SYSCONFDIR
50 #error "SYSCONFDIR is not defined but required."
52 #define LIBNFC_SYSCONFDIR SYSCONFDIR"/nfc"
53 #endif // LIBNFC_SYSCONFDIR
55 #define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
56 #define LIBNFC_DEVICECONFDIR LIBNFC_SYSCONFDIR"/devices.d"
59 conf_parse_file(
const char *filename,
void (*conf_keyvalue)(
void *data,
const char *key,
const char *value),
void *data)
61 FILE *f = fopen(filename,
"r");
63 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO,
"Unable to open file: %s", filename);
67 const char *str_regex =
"^[[:space:]]*([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$";
69 if (regcomp(&preg, str_regex, REG_EXTENDED | REG_NOTEOL) != 0) {
70 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Regular expression used for configuration file parsing is not valid.");
74 size_t nmatch = preg.re_nsub + 1;
75 regmatch_t *pmatch = malloc(
sizeof(*pmatch) * nmatch);
77 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Not enough memory: malloc failed.");
84 while (fgets(line, BUFSIZ, f) != NULL) {
92 if ((match = regexec(&preg, line, nmatch, pmatch, 0)) == 0) {
93 const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so;
94 const off_t value_pmatch = pmatch[3].rm_eo != -1 ? 3 : 4;
95 const size_t value_size = pmatch[value_pmatch].rm_eo - pmatch[value_pmatch].rm_so;
96 char key[key_size + 1];
97 char value[value_size + 1];
98 strncpy(key, line + (pmatch[1].rm_so), key_size);
100 strncpy(value, line + (pmatch[value_pmatch].rm_so), value_size);
101 value[value_size] =
'\0';
102 conf_keyvalue(data, key, value);
104 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"Parse error on line #%d: %s", lineno, line);
118 conf_keyvalue_context(
void *data,
const char *key,
const char *value)
121 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"key: [%s], value: [%s]", key, value);
122 if (strcmp(key,
"allow_autoscan") == 0) {
123 string_as_boolean(value, &(context->allow_autoscan));
124 }
else if (strcmp(key,
"allow_intrusive_scan") == 0) {
125 string_as_boolean(value, &(context->allow_intrusive_scan));
126 }
else if (strcmp(key,
"log_level") == 0) {
127 context->log_level = atoi(value);
128 }
else if (strcmp(key,
"device.name") == 0) {
129 if ((context->user_defined_device_count == 0) || strcmp(context->user_defined_devices[context->user_defined_device_count - 1].name,
"") != 0) {
130 if (context->user_defined_device_count >= MAX_USER_DEFINED_DEVICES) {
131 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Configuration exceeded maximum user-defined devices.");
134 context->user_defined_device_count++;
136 strcpy(context->user_defined_devices[context->user_defined_device_count - 1].name, value);
137 }
else if (strcmp(key,
"device.connstring") == 0) {
138 if ((context->user_defined_device_count == 0) || strcmp(context->user_defined_devices[context->user_defined_device_count - 1].connstring,
"") != 0) {
139 if (context->user_defined_device_count >= MAX_USER_DEFINED_DEVICES) {
140 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Configuration exceeded maximum user-defined devices.");
143 context->user_defined_device_count++;
145 strcpy(context->user_defined_devices[context->user_defined_device_count - 1].connstring, value);
146 }
else if (strcmp(key,
"device.optional") == 0) {
147 if ((context->user_defined_device_count == 0) || context->user_defined_devices[context->user_defined_device_count - 1].optional) {
148 if (context->user_defined_device_count >= MAX_USER_DEFINED_DEVICES) {
149 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Configuration exceeded maximum user-defined devices.");
152 context->user_defined_device_count++;
154 if ((strcmp(value,
"true") == 0) || (strcmp(value,
"True") == 0) || (strcmp(value,
"1") == 0))
155 context->user_defined_devices[context->user_defined_device_count - 1].optional =
true;
157 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO,
"Unknown key in config line: %s = %s", key, value);
162 conf_keyvalue_device(
void *data,
const char *key,
const char *value)
165 sprintf(newkey,
"device.%s", key);
166 conf_keyvalue_context(data, newkey, value);
170 conf_devices_load(
const char *dirname,
nfc_context *context)
172 DIR *d = opendir(dirname);
174 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"Unable to open directory: %s", dirname);
178 struct dirent *result;
179 while ((readdir_r(d, &entry, &result) == 0) && (result != NULL)) {
181 if (de->d_name[0] !=
'.') {
182 const size_t filename_len = strlen(de->d_name);
183 const size_t extension_len = strlen(
".conf");
184 if ((filename_len > extension_len) &&
185 (strncmp(
".conf", de->d_name + (filename_len - extension_len), extension_len) == 0)) {
186 char filename[BUFSIZ] = LIBNFC_DEVICECONFDIR
"/";
187 strcat(filename, de->d_name);
189 if (stat(filename, &s) == -1) {
193 if (S_ISREG(s.st_mode)) {
194 conf_parse_file(filename, conf_keyvalue_device, context);
206 conf_parse_file(LIBNFC_CONFFILE, conf_keyvalue_context, context);
207 conf_devices_load(LIBNFC_DEVICECONFDIR, context);