* $s -> server name (hostname if it doesn't exist)
* $u -> username (guest is usually nobody)
* $v -> volume name or basename if null
- * $z -> zone (may not exist)
* $$ -> $
*
* This get's called from readvolfile with
DSI *dsi = obj->dsi;
q = getip_string((struct sockaddr *)&dsi->client);
} else if (is_var(p, "$s")) {
- if (obj->Obj)
- q = obj->Obj;
- else if (obj->options.server) {
- q = obj->options.server;
- } else
- q = obj->options.hostname;
+ q = obj->options.hostname;
} else if (obj->username && is_var(p, "$u")) {
if (afpmaster && xlatevolname)
return NULL;
else if (*(q + 1) != '\0')
q++;
}
- } else if (is_var(p, "$z")) {
- q = obj->Zone;
} else if (is_var(p, "$$")) {
q = "$";
} else
}
/* -------------------- */
-static void setoption(struct vol_option *options, struct vol_option *save, int opt, const char *val)
+static void setoption(struct vol_option *options, const struct vol_option *save, int opt, const char *val)
{
if (options[opt].c_value && (!save || options[opt].c_value != save[opt].c_value))
free(options[opt].c_value);
static void volset(const dictionary *conf, const char *vol, struct vol_option *options, const struct vol_option *save)
{
const char *val;
- const char *p;
+ char *p, *q;
- if (val = iniparser_getstring(conf, vol, "allow"))
+ if (val = iniparser_getstring(conf, vol, "allow", NULL))
setoption(options, save, VOLOPT_ALLOW, val);
- if (val = iniparser_getstring(conf, vol, "deny"))
+ if (val = iniparser_getstring(conf, vol, "deny", NULL))
setoption(options, save, VOLOPT_DENY, val);
- if (val = iniparser_getstring(conf, vol, "rwlist"))
+ if (val = iniparser_getstring(conf, vol, "rwlist", NULL))
setoption(options, save, VOLOPT_RWLIST, val);
- if (val = iniparser_getstring(conf, vol, "rolist"))
+ if (val = iniparser_getstring(conf, vol, "rolist", NULL))
setoption(options, save, VOLOPT_ROLIST, val);
- if (val = iniparser_getstring(conf, vol, "volcharset"))
+ if (val = iniparser_getstring(conf, vol, "volcharset", NULL))
setoption(options, save, VOLOPT_ENCODING, val);
- if (val = iniparser_getstring(conf, vol, "maccharset"))
+ if (val = iniparser_getstring(conf, vol, "maccharset", NULL))
setoption(options, save, VOLOPT_MACCHARSET, val);
- if (val = iniparser_getstring(conf, vol, "veto"))
+ if (val = iniparser_getstring(conf, vol, "veto", NULL))
setoption(options, save, VOLOPT_VETO, val);
- if (val = iniparser_getstring(conf, vol, "cnidscheme"))
+ if (val = iniparser_getstring(conf, vol, "cnidscheme", NULL))
setoption(options, save, VOLOPT_CNIDSCHEME, val);
- if (val = iniparser_getstring(conf, vol, "dbpath"))
+ if (val = iniparser_getstring(conf, vol, "dbpath", NULL))
setoption(options, save, VOLOPT_DBPATH, val);
- if (val = iniparser_getstring(conf, vol, "password"))
+ if (val = iniparser_getstring(conf, vol, "password", NULL))
setoption(options, save, VOLOPT_PASSWORD, val);
- if (val = iniparser_getstring(conf, vol, "root_preexec"))
+ if (val = iniparser_getstring(conf, vol, "root_preexec", NULL))
setoption(options, save, VOLOPT_ROOTPREEXEC, val);
- if (val = iniparser_getstring(conf, vol, "preexec"))
+ if (val = iniparser_getstring(conf, vol, "preexec", NULL))
setoption(options, save, VOLOPT_PREEXEC, val);
- if (val = iniparser_getstring(conf, vol, "root_postexec"))
+ if (val = iniparser_getstring(conf, vol, "root_postexec", NULL))
setoption(options, save, VOLOPT_ROOTPOSTEXEC, val);
- if (val = iniparser_getstring(conf, vol, "postexec"))
+ if (val = iniparser_getstring(conf, vol, "postexec", NULL))
setoption(options, save, VOLOPT_POSTEXEC, val);
- if (val = iniparser_getstring(conf, vol, "allowed_hosts"))
+ if (val = iniparser_getstring(conf, vol, "allowed_hosts", NULL))
setoption(options, save, VOLOPT_ALLOWED_HOSTS, val);
- if (val = iniparser_getstring(conf, vol, "denied_hosts"))
+ if (val = iniparser_getstring(conf, vol, "denied_hosts", NULL))
setoption(options, save, VOLOPT_DENIED_HOSTS, val);
- if (val = iniparser_getstring(conf, vol, "umask"))
+ if (val = iniparser_getstring(conf, vol, "umask", NULL))
options[VOLOPT_UMASK].i_value = (int)strtol(val, NULL, 8);
- if (val = iniparser_getstring(conf, vol, "dperm"))
+ if (val = iniparser_getstring(conf, vol, "dperm", NULL))
options[VOLOPT_DPERM].i_value = (int)strtol(val, NULL, 8);
- if (val = iniparser_getstring(conf, vol, "fperm"))
+ if (val = iniparser_getstring(conf, vol, "fperm", NULL))
options[VOLOPT_FPERM].i_value = (int)strtol(val, NULL, 8);
- if (val = iniparser_getstring(conf, vol, "perm"))
+ if (val = iniparser_getstring(conf, vol, "perm", NULL))
options[VOLOPT_DFLTPERM].i_value = (int)strtol(val, NULL, 8);
- if (val = iniparser_getstring(conf, vol, "volsizelimit"))
+ if (val = iniparser_getstring(conf, vol, "volsizelimit", NULL))
options[VOLOPT_LIMITSIZE].i_value = (uint32_t)strtoul(val, NULL, 10);
- if (val = iniparser_getstring(conf, vol, "casefold")) {
+ if (val = iniparser_getstring(conf, vol, "casefold", NULL)) {
if (strcasecmp(val, "tolower") == 0)
options[VOLOPT_CASEFOLD].i_value = AFPVOL_UMLOWER;
else if (strcasecmp(val, "toupper") == 0)
options[VOLOPT_CASEFOLD].i_value = AFPVOL_ULOWERMUPPER;
}
- if (val = iniparser_getstring(conf, vol, "adouble")) {
+ if (val = iniparser_getstring(conf, vol, "adouble", NULL)) {
if (strcasecmp(val, "v2") == 0)
options[VOLOPT_ADOUBLE].i_value = AD_VERSION2;
else if (strcasecmp(val, "ea") == 0)
options[VOLOPT_ADOUBLE].i_value = AD_VERSION_EA;
}
- if (val = iniparser_getstring(conf, vol, "ea")) {
+ if (val = iniparser_getstring(conf, vol, "ea", NULL)) {
if (strcasecmp(val, "ad") == 0)
options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AD;
else if (strcasecmp(val, "sys") == 0)
options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_NONE;
}
- if (val = iniparser_getstrdup(conf, vol, "cnidserver")) {
- if (p = strrchr(val, ':')) {
- *p = 0;
- setoption(options, save, VOLOPT_CNIDPORT, p + 1);
+ if (p = iniparser_getstrdup(conf, vol, "cnidserver", NULL)) {
+ if (q = strrchr(val, ':')) {
+ *q = 0;
+ setoption(options, save, VOLOPT_CNIDPORT, q + 1);
}
- setoption(options, save, VOLOPT_CNIDSERVER, val);
+ setoption(options, save, VOLOPT_CNIDSERVER, p);
LOG(log_debug, logtype_afpd, "CNID Server for volume '%s': %s:%s",
- volname, val, p ? p + 1 : Cnid_port);
- free(val);
+ vol, p, q ? q + 1 : "4700");
+ free(p);
}
- if (val = iniparser_getstrdup(conf, vol, "options")) {
- if (p = strtok(val, ",")) {
+ if (q = iniparser_getstrdup(conf, vol, "options", NULL)) {
+ if (p = strtok(q, ",")) {
while (p) {
if (strcasecmp(p, "ro") == 0)
options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
p = strtok(NULL, ",");
}
}
- free(val);
+ free(q);
}
}
if ((p = strtok_r(buf, ",", &b)) == NULL) /* nothing, return okay */
return -1;
- if (obj->proto != AFPPROTO_DSI)
- return -1;
-
while (p) {
int ret;
char *ipaddr, *mask_char;
/* ----------------------
*/
-static int volfile_changed(struct afp_volume_name *p)
+static int volfile_changed(struct afp_options *p)
{
struct stat st;
- char *name;
-
- if (p->full_name)
- name = p->full_name;
- else
- name = p->name;
- if (!stat( name, &st) && st.st_mtime > p->mtime) {
- p->mtime = st.st_mtime;
+ if (!stat(p->configfile, &st) && st.st_mtime > p->volfile.mtime) {
+ p->volfile.mtime = st.st_mtime;
return 1;
}
return 0;
static int vol_section(const char *sec)
{
- if (STRCMP(sec, ==, INISEC_GLOBAL) == 0)
+ if (STRCMP(sec, ==, INISEC_GLOBAL))
return 0;
- if (strcmp(sec, INISEC_AFP) == 0)
+ if (STRCMP(sec, ==, INISEC_AFP))
return 0;
- if (strcmp(sec, INISEC_CNID) == 0)
+ if (STRCMP(sec, ==, INISEC_CNID))
return 0;
return 1;
}
char path[MAXPATHLEN + 1];
char volname[AFPVOL_U8MNAMELEN + 1];
char tmp[MAXPATHLEN + 1];
- char *u, *p;
+ char *u;
+ const char *p;
int fd;
int i;
struct passwd *pw;
struct vol_option default_options[VOLOPT_NUM];
struct vol_option options[VOLOPT_NUM];
- LOG(log_debug, logtype_afpd, "readvolfile(\"%s\"): BEGIN", p1->name);
+ LOG(log_debug, logtype_afpd, "readvolfile: BEGIN");
- if (!p1->name)
- return -1;
p1->mtime = 0;
memset(default_options, 0, sizeof(default_options));
memcpy(save_options, default_options, sizeof(options));
int secnum = iniparser_getnsec(obj->iniconfig);
+ LOG(log_debug, logtype_afpd, "readvolfile: sections: %d", secnum);
const char *secname;
- for (i = 0; i < secnum; secname = iniparser_getsecname(obj->iniconfig, i), i++) {
+ for (i = 0; i < secnum; i++) {
+ secname = iniparser_getsecname(obj->iniconfig, i);
if (!vol_section(secname))
continue;
- if ((p = iniparser_getstring(obj->iniconfig, secname, "path")) == NULL)
+
+ strlcpy(volname, secname, AFPVOL_U8MNAMELEN);
+ LOG(log_debug, logtype_afpd, "readvolfile: volume: %s", volname);
+
+ if ((p = iniparser_getstrdup(obj->iniconfig, secname, "path", NULL)) == NULL)
continue;
strlcpy(path, p, MAXPATHLEN);
strcpy(tmp, path);
- strlcpy(volname, secname, AFPVOL_U8MNAMELEN);
+
if (!pwent && obj->username)
pwent = getpwnam(obj->username);
options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
/* do variable substitution for volname */
- if (volxlate(obj, tmp, sizeof(tmp) - 1, secname, pwent, path, NULL) == NULL) {
+ if (volxlate(obj, tmp, sizeof(tmp) - 1, volname, pwent, path, NULL) == NULL) {
volfree(options, default_options);
continue;
}
int fd = -1;
struct passwd *pwent;
struct stat st;
+ int retries = 0;
if (parent_or_child == 0) {
LOG(log_debug, logtype_afpd, "load_volumes: AFP MASTER");
LOG(log_debug, logtype_afpd, "load_volumes: user: %s", obj->username);
}
- if (Volumes && volfile_changed(&obj->options.volfile))
+ if (Volumes) {
+ if (!volfile_changed(&obj->options))
+ return;
free_volumes();
+ }
/* try putting a read lock on the volume file twice, sleep 1 second if first attempt fails */
- int retries = 2;
- fd = open(p1->name, O_RDWR);
- if (fd != -1 && fstat(fd, &st) == 0)
- p1->mtime = st.st_mtime;
- while (1) {
+
+ fd = open(obj->options.configfile, O_RDWR);
+
+ while (retries < 2) {
if ((read_lock(fd, 0, SEEK_SET, 0)) != 0) {
- retries--;
+ retries++;
if (!retries) {
- LOG(log_error, logtype_afpd, "readvolfile: can't lock volume file \"%s\"", path);
+ LOG(log_error, logtype_afpd, "readvolfile: can't lock configfile \"%s\"",
+ obj->options.configfile);
EC_FAIL;
}
sleep(1);
break;
}
- iniparser_freedict(obj->iniconfig);
- obj->iniconfig = iniparser_load(obj->configfile);
+ if (obj->iniconfig)
+ iniparser_freedict(obj->iniconfig);
+ LOG(log_debug, logtype_afpd, "load_volumes: reloading: %s", obj->options.configfile);
+ obj->iniconfig = iniparser_load(obj->options.configfile);
if (obj->username)
pwent = getpwnam(obj->username);
EC_CLEANUP:
if (fd != -1)
(void)close(fd);
- EC_EXIT;
+ return;
}
/* ------------------------------- */
}
/* ------------------------- */
-static int volume_openDB(struct vol *volume)
+static int volume_openDB(const AFPObj *obj, struct vol *volume)
{
int flags = 0;
}
LOG(log_info, logtype_afpd, "CNID server: %s:%s",
- volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
- volume->v_cnidport ? volume->v_cnidport : Cnid_port);
-
-#if 0
-/* Found this in branch dir-rewrite, maybe we want to use it sometimes */
-
- /* Legacy pre 2.1 way of sharing eg CD-ROM */
- if (strcmp(volume->v_cnidscheme, "last") == 0) {
- /* "last" is gone. We support it by switching to in-memory "tdb" */
- volume->v_cnidscheme = strdup("tdb");
- flags |= CNID_FLAG_MEMORY;
- }
-
- /* New way of sharing CD-ROM */
- if (volume->v_flags & AFPVOL_CDROM) {
- flags |= CNID_FLAG_MEMORY;
- if (strcmp(volume->v_cnidscheme, "tdb") != 0) {
- free(volume->v_cnidscheme);
- volume->v_cnidscheme = strdup("tdb");
- LOG(log_info, logtype_afpd, "Volume %s is ejectable, switching to scheme %s.",
- volume->v_path, volume->v_cnidscheme);
- }
- }
-#endif
+ volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv,
+ volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port);
volume->v_cdb = cnid_open(volume->v_path,
volume->v_umask,
volume->v_cnidscheme,
flags,
- volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
- volume->v_cnidport ? volume->v_cnidport : Cnid_port);
+ volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv,
+ volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port);
if ( ! volume->v_cdb && ! (flags & CNID_FLAG_MEMORY)) {
/* The first attempt failed and it wasn't yet an attempt to open in-memory */
volume->v_root = dir;
curdir = dir;
- if (volume_openDB(volume) < 0) {
+ if (volume_openDB(obj, volume) < 0) {
LOG(log_error, logtype_afpd, "Fatal error: cannot open CNID or invalid CNID backend for %s: %s",
volume->v_path, volume->v_cnidscheme);
ret = AFPERR_MISC;
if (ret == AFP_OK) {
handle_special_folders(volume);
savevolinfo(volume,
- volume->v_cnidserver ? volume->v_cnidserver : Cnid_srv,
- volume->v_cnidport ? volume->v_cnidport : Cnid_port);
+ volume->v_cnidserver ? volume->v_cnidserver : obj->options.Cnid_srv,
+ volume->v_cnidport ? volume->v_cnidport : obj->options.Cnid_port);
/*
return( vol );
}
-/* ------------------------ */
-static int ext_cmp_key(const void *key, const void *obj)
-{
- const char *p = key;
- const struct extmap *em = obj;
- return strdiacasecmp(p, em->em_ext);
-}
-struct extmap *getextmap(const char *path)
-{
- char *p;
- struct extmap *em;
-
- if (!Extmap_cnt || NULL == ( p = strrchr( path, '.' )) ) {
- return( Defextmap );
- }
- p++;
- if (!*p) {
- return( Defextmap );
- }
- em = bsearch(p, Extmap, Extmap_cnt, sizeof(struct extmap), ext_cmp_key);
- if (em) {
- return( em );
- } else {
- return( Defextmap );
- }
-}
-
-/* ------------------------- */
-struct extmap *getdefextmap(void)
-{
- return( Defextmap );
-}
-
/* --------------------------
poll if a volume is changed by other processes.
return
struct timeval tv;
struct stat st;
- if (!(afp_version > 21 && obj->options.server_notif))
+ if (!(afp_version > 21 && obj->options.flags & OPTION_SERVERNOTIF))
return 0;
if ( gettimeofday( &tv, NULL ) < 0 )
/* or finder doesn't update free space
* AFP 3.2 and above clients seem to be ok without so many notification
*/
- if (afp_version < 32 && obj->options.server_notif) {
+ if (afp_version < 32 && obj->options.flags & OPTION_SERVERNOTIF) {
obj->attention(obj->dsi, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED);
}
}