+#ifdef WITH_DYNAMIC_CLIENTS
+#ifdef HAVE_DIRENT_H
+ if (c->client_server) {
+ const char *value;
+ CONF_PAIR *cp;
+ DIR *dir;
+ struct dirent *dp;
+ struct stat stat_buf;
+ char buf2[2048];
+
+ /*
+ * Find the directory where individual
+ * client definitions are stored.
+ */
+ cp = cf_pair_find(cs, "directory");
+ if (!cp) goto add_client;
+
+ value = cf_pair_value(cp);
+ if (!value) {
+ cf_log_err(cf_sectiontoitem(cs),
+ "The \"directory\" entry must not be empty");
+ client_free(c);
+ return NULL;
+ }
+
+ DEBUG("including dynamic clients in %s", value);
+
+ dir = opendir(value);
+ if (!dir) {
+ cf_log_err(cf_sectiontoitem(cs), "Error reading directory %s: %s", value, strerror(errno));
+ client_free(c);
+ return NULL;
+ }
+
+ /*
+ * Read the directory, ignoring "." files.
+ */
+ while ((dp = readdir(dir)) != NULL) {
+ const char *p;
+ RADCLIENT *dc;
+
+ if (dp->d_name[0] == '.') continue;
+
+ /*
+ * Check for valid characters
+ */
+ for (p = dp->d_name; *p != '\0'; p++) {
+ if (isalpha((int)*p) ||
+ isdigit((int)*p) ||
+ (*p == ':') ||
+ (*p == '.')) continue;
+ break;
+ }
+ if (*p != '\0') continue;
+
+ snprintf(buf2, sizeof(buf2), "%s/%s",
+ value, dp->d_name);
+
+ if ((stat(buf2, &stat_buf) != 0) ||
+ S_ISDIR(stat_buf.st_mode)) continue;
+
+ dc = client_read(buf2, in_server, TRUE);
+ if (!dc) {
+ cf_log_err(cf_sectiontoitem(cs),
+ "Failed reading client file \"%s\"", buf2);
+ client_free(c);
+ return NULL;
+ }
+
+ /*
+ * Validate, and add to the list.
+ */
+ if (!client_validate(clients, c, dc)) {
+
+ client_free(c);
+ return NULL;
+ }
+ } /* loop over the directory */
+ }
+#endif /* HAVE_DIRENT_H */
+#endif /* WITH_DYNAMIC_CLIENTS */
+
+ add_client: