1 /*
2 Copyright (c) 2009-2020 Roger Light <roger@atchoo.org>
3
4 All rights reserved. This program and the accompanying materials
5 are made available under the terms of the Eclipse Public License v1.0
6 and Eclipse Distribution License v1.0 which accompany this distribution.
7
8 The Eclipse Public License is available at
9 http://www.eclipse.org/legal/epl-v10.html
10 and the Eclipse Distribution License is available at
11 http://www.eclipse.org/org/documents/edl-v10.php.
12
13 Contributors:
14 Roger Light - initial implementation and documentation.
15 */
16
17 #include "config.h"
18
19 #include <ctype.h>
20 #include <limits.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25
26 #ifdef WIN32
27 #else
28 # include <dirent.h>
29 #endif
30
31 #ifndef WIN32
32 # include <strings.h>
33 # include <netdb.h>
34 # include <sys/socket.h>
35 #else
36 # include <winsock2.h>
37 # include <ws2tcpip.h>
38 #endif
39
40 #if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__QNX__)
41 # include <sys/syslog.h>
42 #endif
43
44 #include "mosquitto_broker_internal.h"
45 #include "memory_mosq.h"
46 #include "tls_mosq.h"
47 #include "util_mosq.h"
48 #include "mqtt_protocol.h"
49
50
scmp_p(const void * p1,const void * p2)51 int scmp_p(const void *p1, const void *p2)
52 {
53 const char *s1 = *(const char **)p1;
54 const char *s2 = *(const char **)p2;
55 int result;
56
57 while(s1[0] && s2[0]){
58 /* Sort by case insensitive part first */
59 result = toupper(s1[0]) - toupper(s2[0]);
60 if(result == 0){
61 /* Case insensitive part matched, now distinguish between case */
62 result = s1[0] - s2[0];
63 if(result != 0){
64 return result;
65 }
66 }else{
67 /* Return case insensitive match fail */
68 return result;
69 }
70 s1++;
71 s2++;
72 }
73
74 return s1[0] - s2[0];
75 }
76
77 #ifdef WIN32
config__get_dir_files(const char * include_dir,char *** files,int * file_count)78 int config__get_dir_files(const char *include_dir, char ***files, int *file_count)
79 {
80 int len;
81 int i;
82 char **l_files = NULL;
83 int l_file_count = 0;
84 char **files_tmp;
85
86 HANDLE fh;
87 char dirpath[MAX_PATH];
88 WIN32_FIND_DATA find_data;
89
90 snprintf(dirpath, MAX_PATH, "%s\\*.conf", include_dir);
91 fh = FindFirstFile(dirpath, &find_data);
92 if(fh == INVALID_HANDLE_VALUE){
93 log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open include_dir '%s'.", include_dir);
94 return 1;
95 }
96
97 do{
98 len = strlen(include_dir)+1+strlen(find_data.cFileName)+1;
99
100 l_file_count++;
101 files_tmp = mosquitto__realloc(l_files, l_file_count*sizeof(char *));
102 if(!files_tmp){
103 for(i=0; i<l_file_count-1; i++){
104 mosquitto__free(l_files[i]);
105 }
106 mosquitto__free(l_files);
107 FindClose(fh);
108 return MOSQ_ERR_NOMEM;
109 }
110 l_files = files_tmp;
111
112 l_files[l_file_count-1] = mosquitto__malloc(len+1);
113 if(!l_files[l_file_count-1]){
114 for(i=0; i<l_file_count-1; i++){
115 mosquitto__free(l_files[i]);
116 }
117 mosquitto__free(l_files);
118 FindClose(fh);
119 return MOSQ_ERR_NOMEM;
120 }
121 snprintf(l_files[l_file_count-1], len, "%s/%s", include_dir, find_data.cFileName);
122 l_files[l_file_count-1][len] = '\0';
123 }while(FindNextFile(fh, &find_data));
124
125 FindClose(fh);
126
127 if(l_files){
128 qsort(l_files, l_file_count, sizeof(char *), scmp_p);
129 }
130 *files = l_files;
131 *file_count = l_file_count;
132
133 return 0;
134 }
135 #endif
136
137
138 #ifndef WIN32
139
config__get_dir_files(const char * include_dir,char *** files,int * file_count)140 int config__get_dir_files(const char *include_dir, char ***files, int *file_count)
141 {
142 char **l_files = NULL;
143 int l_file_count = 0;
144 char **files_tmp;
145 int len;
146 int i;
147
148 DIR *dh;
149 struct dirent *de;
150
151 dh = opendir(include_dir);
152 if(!dh){
153 log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open include_dir '%s'.", include_dir);
154 return 1;
155 }
156 while((de = readdir(dh)) != NULL){
157 if(strlen(de->d_name) > 5){
158 if(!strcmp(&de->d_name[strlen(de->d_name)-5], ".conf")){
159 len = strlen(include_dir)+1+strlen(de->d_name)+1;
160
161 l_file_count++;
162 files_tmp = mosquitto__realloc(l_files, l_file_count*sizeof(char *));
163 if(!files_tmp){
164 for(i=0; i<l_file_count-1; i++){
165 mosquitto__free(l_files[i]);
166 }
167 mosquitto__free(l_files);
168 closedir(dh);
169 return MOSQ_ERR_NOMEM;
170 }
171 l_files = files_tmp;
172
173 l_files[l_file_count-1] = mosquitto__malloc(len+1);
174 if(!l_files[l_file_count-1]){
175 for(i=0; i<l_file_count-1; i++){
176 mosquitto__free(l_files[i]);
177 }
178 mosquitto__free(l_files);
179 closedir(dh);
180 return MOSQ_ERR_NOMEM;
181 }
182 snprintf(l_files[l_file_count-1], len, "%s/%s", include_dir, de->d_name);
183 l_files[l_file_count-1][len] = '\0';
184 }
185 }
186 }
187 closedir(dh);
188
189 if(l_files){
190 qsort(l_files, l_file_count, sizeof(char *), scmp_p);
191 }
192 *files = l_files;
193 *file_count = l_file_count;
194
195 return 0;
196 }
197 #endif
198
199
200