29 #endif // HAVE_CONFIG_H
45 #define LOG_CATEGORY "libnfc.config"
46 #define LOG_GROUP NFC_LOG_GROUP_CONFIG
48 #ifndef LIBNFC_SYSCONFDIR
51 #error "SYSCONFDIR is not defined but required."
53 #define LIBNFC_SYSCONFDIR SYSCONFDIR"/nfc"
54 #endif // LIBNFC_SYSCONFDIR
56 #define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
57 #define LIBNFC_DEVICECONFDIR LIBNFC_SYSCONFDIR"/devices.d"
60 conf_parse_file(
const char *filename,
void (*conf_keyvalue)(
void *data,
const char *key,
const char *value),
void *data)
62 FILE *f = fopen(filename,
"r");
64 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO,
"Unable to open file: %s", filename);
68 const char *str_regex =
"^[[:space:]]*([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$";
70 if (regcomp(&preg, str_regex, REG_EXTENDED | REG_NOTEOL) != 0) {
71 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Regular expression used for configuration file parsing is not valid.");
75 size_t nmatch = preg.re_nsub + 1;
76 regmatch_t *pmatch = malloc(
sizeof(*pmatch) * nmatch);
78 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Not enough memory: malloc failed.");
85 while (fgets(line, BUFSIZ, f) != NULL) {
93 if ((match = regexec(&preg, line, nmatch, pmatch, 0)) == 0) {
94 const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so;
95 const off_t value_pmatch = pmatch[3].rm_eo != -1 ? 3 : 4;
96 const size_t value_size = pmatch[value_pmatch].rm_eo - pmatch[value_pmatch].rm_so;
97 char key[key_size + 1];
98 char value[value_size + 1];
99 strncpy(key, line + (pmatch[1].rm_so), key_size);
100 key[key_size] =
'\0';
101 strncpy(value, line + (pmatch[value_pmatch].rm_so), value_size);
102 value[value_size] =
'\0';
103 conf_keyvalue(data, key, value);
105 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"Parse error on line #%d: %s", lineno, line);
119 conf_keyvalue_context(
void *data,
const char *key,
const char *value)
122 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"key: [%s], value: [%s]", key, value);
123 if (strcmp(key,
"allow_autoscan") == 0) {
124 string_as_boolean(value, &(context->allow_autoscan));
125 }
else if (strcmp(key,
"allow_intrusive_scan") == 0) {
126 string_as_boolean(value, &(context->allow_intrusive_scan));
127 }
else if (strcmp(key,
"log_level") == 0) {
128 context->log_level = atoi(value);
129 }
else if (strcmp(key,
"device.name") == 0) {
130 if ((context->user_defined_device_count == 0) || strcmp(context->user_defined_devices[context->user_defined_device_count - 1].name,
"") != 0) {
131 if (context->user_defined_device_count >= MAX_USER_DEFINED_DEVICES) {
132 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Configuration exceeded maximum user-defined devices.");
135 context->user_defined_device_count++;
137 strncpy(context->user_defined_devices[context->user_defined_device_count - 1].name, value, DEVICE_NAME_LENGTH - 1);
138 context->user_defined_devices[context->user_defined_device_count - 1].name[DEVICE_NAME_LENGTH - 1] =
'\0';
139 }
else if (strcmp(key,
"device.connstring") == 0) {
140 if ((context->user_defined_device_count == 0) || strcmp(context->user_defined_devices[context->user_defined_device_count - 1].connstring,
"") != 0) {
141 if (context->user_defined_device_count >= MAX_USER_DEFINED_DEVICES) {
142 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Configuration exceeded maximum user-defined devices.");
145 context->user_defined_device_count++;
147 strncpy(context->user_defined_devices[context->user_defined_device_count - 1].connstring, value, NFC_BUFSIZE_CONNSTRING - 1);
148 context->user_defined_devices[context->user_defined_device_count - 1].connstring[NFC_BUFSIZE_CONNSTRING - 1] =
'\0';
149 }
else if (strcmp(key,
"device.optional") == 0) {
150 if ((context->user_defined_device_count == 0) || context->user_defined_devices[context->user_defined_device_count - 1].optional) {
151 if (context->user_defined_device_count >= MAX_USER_DEFINED_DEVICES) {
152 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR,
"%s",
"Configuration exceeded maximum user-defined devices.");
155 context->user_defined_device_count++;
157 if ((strcmp(value,
"true") == 0) || (strcmp(value,
"True") == 0) || (strcmp(value,
"1") == 0))
158 context->user_defined_devices[context->user_defined_device_count - 1].optional =
true;
160 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO,
"Unknown key in config line: %s = %s", key, value);
165 conf_keyvalue_device(
void *data,
const char *key,
const char *value)
168 sprintf(newkey,
"device.%s", key);
169 conf_keyvalue_context(data, newkey, value);
173 conf_devices_load(
const char *dirname,
nfc_context *context)
175 DIR *d = opendir(dirname);
177 log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG,
"Unable to open directory: %s", dirname);
181 while ((de = readdir(d)) != NULL) {
184 struct dirent *result;
185 while ((readdir_r(d, &entry, &result) == 0) && (result != NULL)) {
188 if (de->d_name[0] !=
'.') {
189 const size_t filename_len = strlen(de->d_name);
190 const size_t extension_len = strlen(
".conf");
191 if ((filename_len > extension_len) &&
192 (strncmp(
".conf", de->d_name + (filename_len - extension_len), extension_len) == 0)) {
193 char filename[BUFSIZ] = LIBNFC_DEVICECONFDIR
"/";
194 strcat(filename, de->d_name);
196 if (stat(filename, &s) == -1) {
200 if (S_ISREG(s.st_mode)) {
201 conf_parse_file(filename, conf_keyvalue_device, context);
213 conf_parse_file(LIBNFC_CONFFILE, conf_keyvalue_context, context);
214 conf_devices_load(LIBNFC_DEVICECONFDIR, context);