Skip to content

Commit 011122a

Browse files
committed
libatalk: Support for loading multiple afp.conf files with -F, GitHub #1982
1 parent 73d38df commit 011122a

File tree

4 files changed

+87
-19
lines changed

4 files changed

+87
-19
lines changed

etc/afpd/afprun.c

+1-14
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,7 @@
4646
#endif
4747

4848
#include <atalk/logger.h>
49-
50-
/****************************************************************************
51-
Find a suitable temporary directory. The result should be copied immediately
52-
as it may be overwritten by a subsequent call.
53-
****************************************************************************/
54-
55-
static const char *tmpdir(void)
56-
{
57-
char *p;
58-
59-
if ((p = getenv("TMPDIR")))
60-
return p;
61-
return "/tmp";
62-
}
49+
#include <atalk/util.h>
6350

6451
/****************************************************************************
6552
This is a utility function of afprun().

include/atalk/util.h

+1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ extern int recv_fd(int fd, int nonblocking);
202202
* unix.c
203203
*****************************************************************/
204204

205+
extern const char *tmpdir(void);
205206
extern const char *getcwdpath(void);
206207
extern const char *fullpathname(const char *);
207208
extern char *stripped_slashes_basename(char *p);

libatalk/util/netatalk_conf.c

+71-5
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,14 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
21412141
char *q = NULL;
21422142
char *r = NULL;
21432143
char val[MAXVAL];
2144+
char *configfiles = NULL;
2145+
char *token = NULL;
2146+
char *saveptr = NULL;
2147+
FILE *combined_file = NULL;
2148+
char temp_filename[MAXPATHLEN] = {0};
2149+
char buffer[4096];
2150+
FILE *current_file = NULL;
2151+
size_t bytes_read;
21442152

21452153
if (processname != NULL)
21462154
set_processname(processname);
@@ -2153,11 +2161,69 @@ int afp_config_parse(AFPObj *AFPObj, char *processname)
21532161
options->uuidconf = strdup(_PATH_STATEDIR "afp_voluuid.conf");
21542162
options->flags = OPTION_UUID | AFPObj->cmdlineflags;
21552163

2156-
become_root();
2157-
config = iniparser_load(AFPObj->options.configfile);
2158-
unbecome_root();
2159-
if (config == NULL)
2160-
return -1;
2164+
if (strchr(options->configfile, ',') != NULL) {
2165+
snprintf(temp_filename, sizeof(temp_filename), "%s/afp_combined_XXXXXX", tmpdir());
2166+
int temp_fd = mkstemp(temp_filename);
2167+
if (temp_fd == -1) {
2168+
LOG(log_error, logtype_afpd, "Failed to create temporary file: %s", strerror(errno));
2169+
EC_FAIL;
2170+
}
2171+
2172+
combined_file = fdopen(temp_fd, "w");
2173+
if (!combined_file) {
2174+
close(temp_fd);
2175+
unlink(temp_filename);
2176+
LOG(log_error, logtype_afpd, "Failed to open temporary file: %s", strerror(errno));
2177+
EC_FAIL;
2178+
}
2179+
2180+
EC_NULL_LOG( configfiles = strdup(options->configfile) );
2181+
token = strtok_r(configfiles, ",", &saveptr);
2182+
while (token != NULL) {
2183+
/* Trim whitespace */
2184+
while (*token && isspace(*token))
2185+
token++;
2186+
2187+
LOG(log_debug, logtype_afpd, "Processing config file: %s", token);
2188+
2189+
become_root();
2190+
current_file = fopen(token, "r");
2191+
unbecome_root();
2192+
2193+
if (current_file == NULL) {
2194+
LOG(log_error, logtype_afpd, "Failed to open config file %s: %s",
2195+
token, strerror(errno));
2196+
token = strtok_r(NULL, ",", &saveptr);
2197+
continue;
2198+
}
2199+
2200+
fprintf(combined_file, "\n# Begin included file: %s\n", token);
2201+
2202+
/* Copy the content of the current file to the combined file */
2203+
while ((bytes_read = fread(buffer, 1, sizeof(buffer), current_file)) > 0) {
2204+
fwrite(buffer, 1, bytes_read, combined_file);
2205+
}
2206+
2207+
fprintf(combined_file, "\n# End included file: %s\n", token);
2208+
2209+
fclose(current_file);
2210+
token = strtok_r(NULL, ",", &saveptr);
2211+
}
2212+
2213+
fclose(combined_file);
2214+
become_root();
2215+
config = iniparser_load(temp_filename);
2216+
unbecome_root();
2217+
unlink(temp_filename);
2218+
} else {
2219+
become_root();
2220+
config = iniparser_load(options->configfile);
2221+
unbecome_root();
2222+
}
2223+
2224+
if (config == NULL) {
2225+
EC_FAIL_LOG("Failed to load configuration file(s): %s", options->configfile);
2226+
}
21612227
AFPObj->iniconfig = config;
21622228

21632229
/* [Global] */

libatalk/util/unix.c

+14
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,20 @@ char *stripped_slashes_basename(char *p)
229229
return (strrchr(p, '/') ? strrchr(p, '/') + 1 : p);
230230
}
231231

232+
/****************************************************************************
233+
Find a suitable temporary directory. The result should be copied immediately
234+
as it may be overwritten by a subsequent call.
235+
****************************************************************************/
236+
237+
const char *tmpdir(void)
238+
{
239+
char *p;
240+
241+
if ((p = getenv("TMPDIR")))
242+
return p;
243+
return "/tmp";
244+
}
245+
232246
/*********************************************************************************
233247
* chdir(), chmod(), chown(), stat() wrappers taking an additional option.
234248
* Currently the only used options are O_NOFOLLOW, used to switch between symlink

0 commit comments

Comments
 (0)