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