From df7560dfdb12b06090dc4b2c6e88d0858930b591 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Sat, 11 Feb 2012 10:13:36 +0100 Subject: [PATCH] New option parsing --- configure.ac | 3 - etc/afpd/Makefile.am | 3 - etc/afpd/afp_avahi.c | 2 +- etc/afpd/afp_config.c | 294 ++----------- etc/afpd/afp_config.h | 12 - etc/afpd/afp_dsi.c | 30 +- etc/afpd/afp_options.c | 717 +++++++++----------------------- etc/afpd/auth.c | 8 +- etc/afpd/desktop.c | 8 +- etc/afpd/fork.c | 8 +- etc/afpd/main.c | 98 ++--- etc/afpd/messages.c | 4 +- etc/afpd/status.c | 2 +- etc/afpd/uam.c | 17 +- etc/afpd/volume.c | 10 +- include/atalk/afp.h | 9 - include/atalk/dictionary.h | 117 +----- include/atalk/dsi.h | 166 ++++---- include/atalk/globals.h | 62 +-- include/atalk/iniparser.h | 249 +---------- include/atalk/ldapconfig.h | 4 +- include/atalk/logger.h | 26 +- include/atalk/uam.h | 1 - libatalk/acl/ldap_config.c | 117 ++---- libatalk/dsi/dsi_opensess.c | 6 +- libatalk/iniparser/dictionary.c | 81 ++-- libatalk/iniparser/iniparser.c | 124 +++--- libatalk/util/logger.c | 201 ++++----- macros/srvloc.m4 | 75 ---- 29 files changed, 663 insertions(+), 1791 deletions(-) delete mode 100644 macros/srvloc.m4 diff --git a/configure.ac b/configure.ac index 3f6f9515..dbd9b2b1 100644 --- a/configure.ac +++ b/configure.ac @@ -172,9 +172,6 @@ AC_NETATALK_CNID([bdb_required=yes],[bdb_required=no]) dnl Check for quota support AC_NETATALK_CHECK_QUOTA -dnl Check for optional server location protocol support (used by MacOS X) -AC_NETATALK_SRVLOC - dnl Check for optional Zeroconf support AC_NETATALK_ZEROCONF diff --git a/etc/afpd/Makefile.am b/etc/afpd/Makefile.am index acde6d64..1a2dd95c 100644 --- a/etc/afpd/Makefile.am +++ b/etc/afpd/Makefile.am @@ -55,13 +55,10 @@ afpd_CFLAGS = \ @SLP_CFLAGS@ @ZEROCONF_CFLAGS@ \ -DAPPLCNAME \ -DSERVERTEXT=\"$(SERVERTEXT)/\" \ - -D_PATH_AFPDDEFVOL=\"$(pkgconfdir)/AppleVolumes.default\" \ - -D_PATH_AFPDSYSVOL=\"$(pkgconfdir)/AppleVolumes.system\" \ -D_PATH_AFPDPWFILE=\"$(pkgconfdir)/afppasswd\" \ -D_PATH_AFPDCONF=\"$(pkgconfdir)/afpd.conf\" \ -D_PATH_AFPDSIGCONF=\"$(pkgconfdir)/afp_signature.conf\" \ -D_PATH_AFPDUAMPATH=\"$(UAMS_PATH)/\" \ - -D_PATH_ACL_LDAPCONF=\"$(pkgconfdir)/afp_ldap.conf\" \ -D_PATH_AFPDUUIDCONF=\"$(pkgconfdir)/afp_voluuid.conf\" \ -D_PATH_CONFDIR=\"$(pkgconfdir)\" diff --git a/etc/afpd/afp_avahi.c b/etc/afpd/afp_avahi.c index 351e0019..89ff95fd 100644 --- a/etc/afpd/afp_avahi.c +++ b/etc/afpd/afp_avahi.c @@ -94,7 +94,7 @@ static void register_stuff(void) { /* AFP server */ for (config = ctx->configs; config; config = config->next) { - dsi = (DSI *)config->obj.handle; + dsi = (DSI *)config->obj.dsi; port = getip_port((struct sockaddr *)&dsi->server); if (convert_string(config->obj.options.unixcharset, diff --git a/etc/afpd/afp_config.c b/etc/afpd/afp_config.c index 4b451527..cd332a94 100644 --- a/etc/afpd/afp_config.c +++ b/etc/afpd/afp_config.c @@ -18,30 +18,24 @@ #include #include -#ifdef USE_SRVLOC -#include -#endif /* USE_SRVLOC */ - #include #include #include #include #include #include +#include #ifdef HAVE_LDAP #include #endif -#include #include "afp_config.h" #include "uam_auth.h" #include "status.h" #include "volume.h" #include "afp_zeroconf.h" -#define LINESIZE 1024 - /* get rid of unneeded configurations. i use reference counts to deal * w/ multiple configs sharing the same afp_options. oh, to dream of * garbage collection ... */ @@ -54,16 +48,12 @@ void configfree(AFPConfig *configs, const AFPConfig *config) if (p == config) continue; - /* do a little reference counting */ - if (--(*p->optcount) < 1) { - afp_options_free(&p->obj.options, p->defoptions); - free(p->optcount); - } + afp_options_free(&p->obj.options, p->defoptions); switch (p->obj.proto) { case AFPPROTO_DSI: close(p->fd); - free(p->obj.handle); + free(p->obj.dsi); break; } free(p); @@ -73,95 +63,16 @@ void configfree(AFPConfig *configs, const AFPConfig *config) unload_volumes_and_extmap(); } -#ifdef USE_SRVLOC -static void SRVLOC_callback(SLPHandle hslp _U_, SLPError errcode, void *cookie) { - *(SLPError*)cookie = errcode; -} - -static char hex[17] = "0123456789abcdef"; - -static char * srvloc_encode(const struct afp_options *options, const char *name) -{ - static char buf[512]; - char *conv_name; - unsigned char *p; - unsigned int i = 0; - - /* Convert name to maccharset */ - if ((size_t)-1 ==(convert_string_allocate( options->unixcharset, options->maccharset, - name, -1, &conv_name)) ) - return (char*)name; - - /* Escape characters */ - p = conv_name; - while (*p && i<(sizeof(buf)-4)) { - if (*p == '@') - break; - else if (isspace(*p)) { - buf[i++] = '%'; - buf[i++] = '2'; - buf[i++] = '0'; - p++; - } - else if ((!isascii(*p)) || *p <= 0x2f || *p == 0x3f ) { - buf[i++] = '%'; - buf[i++] = hex[*p >> 4]; - buf[i++] = hex[*p++ & 15]; - } - else { - buf[i++] = *p++; - } - } - buf[i] = '\0'; - - free (conv_name); - - return buf; -} -#endif /* USE_SRVLOC */ static void dsi_cleanup(const AFPConfig *config) { -#ifdef USE_SRVLOC - SLPError err; - SLPError callbackerr; - SLPHandle hslp; - DSI *dsi = (DSI *)config->obj.handle; - - /* Do nothing if we didn't register. */ - if (!dsi || dsi->srvloc_url[0] == '\0') - return; - - err = SLPOpen("en", SLP_FALSE, &hslp); - if (err != SLP_OK) { - LOG(log_error, logtype_afpd, "dsi_cleanup: Error opening SRVLOC handle"); - goto srvloc_dereg_err; - } - - err = SLPDereg(hslp, - dsi->srvloc_url, - SRVLOC_callback, - &callbackerr); - if (err != SLP_OK) { - LOG(log_error, logtype_afpd, "dsi_cleanup: Error unregistering %s from SRVLOC", dsi->srvloc_url); - goto srvloc_dereg_err; - } - - if (callbackerr != SLP_OK) { - LOG(log_error, logtype_afpd, "dsi_cleanup: Error in callback while trying to unregister %s from SRVLOC (%d)", dsi->srvloc_url, callbackerr); - goto srvloc_dereg_err; - } - -srvloc_dereg_err: - dsi->srvloc_url[0] = '\0'; - SLPClose(hslp); -#endif /* USE_SRVLOC */ + return; } static afp_child_t *dsi_start(AFPConfig *config, AFPConfig *configs, server_child *server_children) { - DSI *dsi = config->obj.handle; + DSI *dsi = config->obj.dsi; afp_child_t *child = NULL; if (!(child = dsi_getsession(dsi, @@ -204,102 +115,17 @@ static AFPConfig *DSIConfigInit(const struct afp_options *options, if ((dsi = dsi_init(protocol, "afpd", options->hostname, options->ipaddr, options->port, - options->flags & OPTION_PROXY, - options->server_quantum)) == NULL) { + 0, options->server_quantum)) == NULL) { LOG(log_error, logtype_afpd, "main: dsi_init: %s", strerror(errno) ); free(config); return NULL; } dsi->dsireadbuf = options->dsireadbuf; - if (options->flags & OPTION_PROXY) { - LOG(log_note, logtype_afpd, "AFP/TCP proxy initialized for %s:%d (%s)", - getip_string((struct sockaddr *)&dsi->server), getip_port((struct sockaddr *)&dsi->server), VERSION); - } else { - LOG(log_note, logtype_afpd, "AFP/TCP started, advertising %s:%d (%s)", - getip_string((struct sockaddr *)&dsi->server), getip_port((struct sockaddr *)&dsi->server), VERSION); - } + LOG(log_note, logtype_afpd, "AFP/TCP started, advertising %s:%d (%s)", + getip_string((struct sockaddr *)&dsi->server), getip_port((struct sockaddr *)&dsi->server), VERSION); -#ifdef USE_SRVLOC - dsi->srvloc_url[0] = '\0'; /* Mark that we haven't registered. */ - if (!(options->flags & OPTION_NOSLP)) { - SLPError err; - SLPError callbackerr; - SLPHandle hslp; - unsigned int afp_port; - int l; - char *srvloc_hostname; - const char *hostname; - - err = SLPOpen("en", SLP_FALSE, &hslp); - if (err != SLP_OK) { - LOG(log_error, logtype_afpd, "DSIConfigInit: Error opening SRVLOC handle"); - goto srvloc_reg_err; - } - - /* XXX We don't want to tack on the port number if we don't have to. - * Why? - * Well, this seems to break MacOS < 10. If the user _really_ wants to - * use a non-default port, they can, but be aware, this server might - * not show up int the Network Browser. - */ - afp_port = getip_port((struct sockaddr *)&dsi->server); - /* If specified use the FQDN to register with srvloc, otherwise use IP. */ - p = NULL; - if (options->fqdn) { - hostname = options->fqdn; - p = strchr(hostname, ':'); - } - else - hostname = getip_string((struct sockaddr *)&dsi->server); - - srvloc_hostname = srvloc_encode(options, (options->server ? options->server : options->hostname)); - - if ((p) || afp_port == 548) { - l = snprintf(dsi->srvloc_url, sizeof(dsi->srvloc_url), "afp://%s/?NAME=%s", hostname, srvloc_hostname); - } - else { - l = snprintf(dsi->srvloc_url, sizeof(dsi->srvloc_url), "afp://%s:%d/?NAME=%s", hostname, afp_port, srvloc_hostname); - } - - if (l == -1 || l >= (int)sizeof(dsi->srvloc_url)) { - LOG(log_error, logtype_afpd, "DSIConfigInit: Hostname is too long for SRVLOC"); - dsi->srvloc_url[0] = '\0'; - goto srvloc_reg_err; - } - - err = SLPReg(hslp, - dsi->srvloc_url, - SLP_LIFETIME_MAXIMUM, - "afp", - "", - SLP_TRUE, - SRVLOC_callback, - &callbackerr); - if (err != SLP_OK) { - LOG(log_error, logtype_afpd, "DSIConfigInit: Error registering %s with SRVLOC", dsi->srvloc_url); - dsi->srvloc_url[0] = '\0'; - goto srvloc_reg_err; - } - - if (callbackerr != SLP_OK) { - LOG(log_error, logtype_afpd, "DSIConfigInit: Error in callback trying to register %s with SRVLOC", dsi->srvloc_url); - dsi->srvloc_url[0] = '\0'; - goto srvloc_reg_err; - } - - LOG(log_info, logtype_afpd, "Sucessfully registered %s with SRVLOC", dsi->srvloc_url); - config->server_cleanup = dsi_cleanup; - -srvloc_reg_err: - SLPClose(hslp); - } -#endif /* USE_SRVLOC */ - - config->fd = dsi->serversock; - config->obj.handle = dsi; - config->obj.config = config; - config->obj.proto = AFPPROTO_DSI; + config->dsi = dsi; memcpy(&config->obj.options, options, sizeof(struct afp_options)); /* get rid of any appletalk info. we use the fact that the DSI @@ -308,10 +134,6 @@ srvloc_reg_err: if (p && (q = strchr(p, ':'))) *q = '\0'; - config->optcount = refcount; - (*refcount)++; - - config->server_start = dsi_start; return config; } @@ -333,28 +155,13 @@ static AFPConfig *AFPConfigInit(struct afp_options *options, /* set signature */ set_signature(options); - /* handle dsi transports and dsi proxies. we only proxy - * for DSI connections. */ - - /* this should have something like the following: - * for (i=mindsi; i < maxdsi; i++) - * if (options->transports & (1 << i) && - * (next = DSIConfigInit(options, refcount, i))) - * next->defoptions = defoptions; - */ - if ( (options->transports & AFPTRANS_TCP) - && - ((options->flags & OPTION_PROXY) == 0) - && - (next = DSIConfigInit(options, refcount, DSI_TCPIP))) - next->defoptions = defoptions; - - /* load in all the authentication modules. we can load the same - things multiple times if necessary. however, loading different - things with the same names will cause complaints. by not loading - in any uams with proxies, we prevent ddp connections from succeeding. - */ - auth_load(options->uampath, options->uamlist); + if ((next = DSIConfigInit(options, refcount, DSI_TCPIP))) + /* load in all the authentication modules. we can load the same + things multiple times if necessary. however, loading different + things with the same names will cause complaints. by not loading + in any uams with proxies, we prevent ddp connections from succeeding. + */ + auth_load(options->uampath, options->uamlist); /* this should be able to accept multiple dsi transports. i think * the only thing that gets affected is the net addresses. */ @@ -363,72 +170,35 @@ static AFPConfig *AFPConfigInit(struct afp_options *options, return next; } -/* fill in the appropriate bits for each interface */ -AFPConfig *configinit(struct afp_options *cmdline) +/*! + * Parse configfile and build AFPObj + */ +int configinit(AFPObj *AFPObj, const struct afp_options *defoptions) { - FILE *fp; - char buf[LINESIZE + 1], *p, have_option = 0; - size_t len; - struct afp_options options; - AFPConfig *config=NULL, *first = NULL; - - /* if config file doesn't exist, load defaults */ - if ((fp = fopen(cmdline->configfile, "r")) == NULL) - { - LOG(log_debug, logtype_afpd, "ConfigFile %s not found, assuming defaults", - cmdline->configfile); - return AFPConfigInit(cmdline, cmdline); - } + int have_option = 0; - /* scan in the configuration file */ - len = 0; - while (!feof(fp)) { - if (!fgets(&buf[len], LINESIZE - len, fp) || buf[len] == '#') - continue; - len = strlen(buf); - if ( len >= 2 && buf[len-2] == '\\' ) { - len -= 2; - continue; - } else - len = 0; - - /* a little pre-processing to get rid of spaces and end-of-lines */ - p = buf; - while (p && isspace(*p)) - p++; - if (!p || (*p == '\0')) - continue; + afp_options_duplicate(&AFPObj->options, defoptions); - have_option = 1; + if ((AFPObj->iniconfig = iniparser_load(AFPObj->options.configfile)) == NULL) + /* if config file doesn't exist, load defaults */ + return AFPConfigInit(AFPObj); - memcpy(&options, cmdline, sizeof(options)); - if (!afp_options_parseline(p, &options)) - continue; + if (afp_options_parse(AFPObj) != 0) + return -1; - /* AFPConfigInit can return two linked configs due to DSI and ASP */ - if (!first) { - if ((first = AFPConfigInit(&options, cmdline))) - config = first->next ? first->next : first; - } else if ((config->next = AFPConfigInit(&options, cmdline))) { - config = config->next->next ? config->next->next : config->next; - } - } + AFPConfigInit(AFPObj); #ifdef HAVE_LDAP /* Parse afp_ldap.conf */ - acl_ldap_readconfig(_PATH_ACL_LDAPCONF); + acl_ldap_readconfig(AFPObj->iniconfig); #endif /* HAVE_LDAP */ LOG(log_debug, logtype_afpd, "Finished parsing Config File"); - fclose(fp); - - if (!have_option) - first = AFPConfigInit(cmdline, cmdline); /* Now register with zeroconf, we also need the volumes for that */ - if (! (first->obj.options.flags & OPTION_NOZEROCONF)) { - load_volumes(&first->obj); - zeroconf_register(first); + if (! (AFPObj->options.flags & OPTION_NOZEROCONF)) { + load_volumes(AFPObj); + zeroconf_register(AFPObj); } return first; diff --git a/etc/afpd/afp_config.h b/etc/afpd/afp_config.h index 022a6e65..09cad9bb 100644 --- a/etc/afpd/afp_config.h +++ b/etc/afpd/afp_config.h @@ -4,18 +4,6 @@ #include #include -typedef struct AFPConfig { - AFPObj obj; - int fd, statuslen; - unsigned char *optcount; - char status[1400]; - const void *defoptions, *signature; - afp_child_t *(*server_start) (struct AFPConfig *, struct AFPConfig *, - server_child *); - void (*server_cleanup) (const struct AFPConfig *); - struct AFPConfig *next; -} AFPConfig; - extern AFPConfig *configinit (struct afp_options *); extern void configfree (AFPConfig *, const AFPConfig *); diff --git a/etc/afpd/afp_dsi.c b/etc/afpd/afp_dsi.c index 94e6f0c8..47dd4e46 100644 --- a/etc/afpd/afp_dsi.c +++ b/etc/afpd/afp_dsi.c @@ -69,7 +69,7 @@ static rc_elem_t replaycache[REPLAYCACHE_SIZE]; static sigjmp_buf recon_jmp; static void afp_dsi_close(AFPObj *obj) { - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; close(obj->ipc_fd); obj->ipc_fd = -1; @@ -103,7 +103,7 @@ static void afp_dsi_close(AFPObj *obj) */ static void afp_dsi_die(int sig) { - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; if (dsi->flags & DSI_RECONINPROG) { /* Primary reconnect succeeded, got SIGTERM from afpd parent */ @@ -116,7 +116,7 @@ static void afp_dsi_die(int sig) exit(0); } - dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN); + dsi_attention(AFPobj->dsi, AFPATTN_SHUTDOWN); afp_dsi_close(AFPobj); if (sig) /* if no signal, assume dieing because logins are disabled & don't log it (maintenance mode)*/ @@ -132,7 +132,7 @@ static void afp_dsi_die(int sig) /* SIGQUIT handler */ static void ipc_reconnect_handler(int sig _U_) { - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; if (reconnect_ipc(AFPobj) != 0) { LOG(log_error, logtype_afpd, "ipc_reconnect_handler: failed IPC reconnect"); @@ -153,7 +153,7 @@ static void afp_dsi_transfer_session(int sig _U_) { uint16_t dsiID; int socket; - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; LOG(log_debug, logtype_afpd, "afp_dsi_transfer_session: got SIGURG, trying to receive session"); @@ -204,13 +204,13 @@ static void afp_dsi_timedown(int sig _U_) { struct sigaction sv; struct itimerval it; - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; dsi->flags |= DSI_DIE; /* shutdown and don't reconnect. server going down in 5 minutes. */ setmessage("The server is going down for maintenance."); - if (dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT | + if (dsi_attention(AFPobj->dsi, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT | AFPATTN_MESG | AFPATTN_TIME(5)) < 0) { - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; dsi->down_request = 1; } @@ -267,17 +267,17 @@ static void afp_dsi_debug(int sig _U_) /* ---------------------- */ static void afp_dsi_getmesg (int sig _U_) { - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; dsi->msg_request = 1; - if (dsi_attention(AFPobj->handle, AFPATTN_MESG | AFPATTN_TIME(5)) < 0) + if (dsi_attention(AFPobj->dsi, AFPATTN_MESG | AFPATTN_TIME(5)) < 0) dsi->msg_request = 2; } static void alarm_handler(int sig _U_) { int err; - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; /* we have to restart the timer because some libraries may use alarm() */ setitimer(ITIMER_REAL, &dsi->timer, NULL); @@ -331,7 +331,7 @@ static void alarm_handler(int sig _U_) if ((err = pollvoltime(AFPobj)) == 0) LOG(log_debug, logtype_afpd, "afp_alarm: sending DSI tickle"); - err = dsi_tickle(AFPobj->handle); + err = dsi_tickle(AFPobj->dsi); if (err <= 0) { if (geteuid() == 0) { LOG(log_note, logtype_afpd, "afp_alarm: unauthenticated user, connection problem"); @@ -355,14 +355,14 @@ static void pending_request(DSI *dsi) if (dsi->msg_request) { if (dsi->msg_request == 2) { /* didn't send it in signal handler */ - dsi_attention(AFPobj->handle, AFPATTN_MESG | AFPATTN_TIME(5)); + dsi_attention(AFPobj->dsi, AFPATTN_MESG | AFPATTN_TIME(5)); } dsi->msg_request = 0; readmessage(AFPobj); } if (dsi->down_request) { dsi->down_request = 0; - dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT | + dsi_attention(AFPobj->dsi, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT | AFPATTN_MESG | AFPATTN_TIME(5)); } } @@ -372,7 +372,7 @@ static void pending_request(DSI *dsi) */ void afp_over_dsi(AFPObj *obj) { - DSI *dsi = (DSI *) obj->handle; + DSI *dsi = (DSI *) obj->dsi; int rc_idx; uint32_t err, cmd; uint8_t function; diff --git a/etc/afpd/afp_options.c b/etc/afpd/afp_options.c index 256c91a5..65710c10 100644 --- a/etc/afpd/afp_options.c +++ b/etc/afpd/afp_options.c @@ -41,477 +41,250 @@ #include "auth.h" #include "dircache.h" -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif /* MIN */ - -/* FIXME CNID */ -const char *Cnid_srv = "localhost"; -const char *Cnid_port = "4700"; - -#define OPTIONS "dn:f:s:uc:g:P:ptDS:TL:F:U:hIvVm:" +#define OPTIONS "dn:uc:g:P:ptS:L:F:U:hIvVm:" #define LENGTH 512 -/* return an option. this uses an internal array, so it's necessary - * to duplicate it if you want to hold it for long. this is probably - * non-optimal. */ -static char *getoption(char *buf, const char *option) +/* initialize options */ +void afp_options_init(struct afp_options *options) { - static char string[LENGTH + 1]; - char *end; - int len; - - if (option && (buf = strstr(buf, option))) - buf = strpbrk(buf, " \t"); - - while (buf && isspace(*buf)) - buf++; - - if (!buf) - return NULL; - - /* search for any quoted stuff */ - if (*buf == '"' && (end = strchr(buf + 1, '"'))) { - buf++; - len = MIN(end - buf, LENGTH); - } else if ((end = strpbrk(buf, " \t\n"))) /* option or eoln */ - len = MIN(end - buf, LENGTH); - else - len = MIN(strlen(buf), LENGTH); - - strncpy(string, buf, len); - string[len] = '\0'; - return string; + memset(options, 0, sizeof(struct afp_options)); + + options->pidfile = _PATH_AFPDLOCK; + options->configfile = D_PATH_CONFDIR "afp.conf"; + options->sigconffile = _PATH_AFPDSIGCONF; + options->uuidconf = _PATH_AFPDUUIDCONF; + options->server_notif = 1; + options->dsireadbuf = 12; } /* get rid of any allocated afp_option buffers. */ -void afp_options_free(struct afp_options *opt, - const struct afp_options *save) +void afp_options_free(struct afp_options *opt) { - if (opt->defaultvol.name && (opt->defaultvol.name != save->defaultvol.name)) - free(opt->defaultvol.name); - if (opt->defaultvol.full_name && (opt->defaultvol.full_name != save->defaultvol.full_name)) - free(opt->defaultvol.full_name); - - if (opt->systemvol.name && (opt->systemvol.name != save->systemvol.name)) - free(opt->systemvol.name); - if (opt->systemvol.full_name && (opt->systemvol.full_name != save->systemvol.full_name)) - free(opt->systemvol.full_name); - - if (opt->uservol.name && (opt->uservol.name != save->uservol.name)) - free(opt->uservol.name); - if (opt->uservol.full_name && (opt->uservol.full_name != save->uservol.full_name)) - free(opt->uservol.full_name); - - if (opt->loginmesg && (opt->loginmesg != save->loginmesg)) - free(opt->loginmesg); - if (opt->guest && (opt->guest != save->guest)) + if (opt->adminauthuser) + free(opt->adminauthuser); + if (opt->configfile) + free(opt->configfile); + if (opt->fqdn) + free(opt->fqdn); + if (opt->guest) free(opt->guest); - if (opt->server && (opt->server != save->server)) - free(opt->server); - if (opt->ipaddr && (opt->ipaddr != save->ipaddr)) + if (opt->ipaddr) free(opt->ipaddr); - if (opt->port && (opt->port != save->port)) + if (opt->k5realm) + free(opt->k5realm); + if (opt->k5keytab) + free(opt->k5keytab); + if (opt->k5service) + free(opt->k5service); + if (opt->logconfig) + free(opt->logconfig); + if (opt->loginmesg) + free(opt->loginmesg); + if (opt->maccodepage) + free(opt->maccodepage); + if (opt->mimicmodel) + free(opt->mimicmodel); + if (opt->ntdomain) + free(opt->ntdomain); + if (opt->ntseparator) + free(opt->ntseparator); + if (opt->passwdfile) + free(opt->passwdfile); + if (opt->port) free(opt->port); - if (opt->fqdn && (opt->fqdn != save->fqdn)) - free(opt->fqdn); - if (opt->uampath && (opt->uampath != save->uampath)) - free(opt->uampath); - if (opt->uamlist && (opt->uamlist != save->uamlist)) + if (opt->server) + free(opt->server); + if (opt->signatureopt) + free(opt->signatureopt); + if (opt->uamlist) free(opt->uamlist); - if (opt->passwdfile && (opt->passwdfile != save->passwdfile)) - free(opt->passwdfile); - if (opt->signatureopt && (opt->signatureopt != save->signatureopt)) - free(opt->signatureopt); - if (opt->k5service && (opt->k5service != save->k5service)) - free(opt->k5service); - if (opt->k5realm && (opt->k5realm != save->k5realm)) - free(opt->k5realm); - if (opt->k5keytab && (opt->k5keytab != save->k5keytab)) - free(opt->k5keytab); - if (opt->unixcodepage && (opt->unixcodepage != save->unixcodepage)) - free(opt->unixcodepage); - if (opt->maccodepage && (opt->maccodepage != save->maccodepage)) - free(opt->maccodepage); - - if (opt->ntdomain && (opt->ntdomain != save->ntdomain)) - free(opt->ntdomain); - if (opt->ntseparator && (opt->ntseparator != save->ntseparator)) - free(opt->ntseparator); - if (opt->logconfig && (opt->logconfig != save->logconfig)) - free(opt->logconfig); - if (opt->mimicmodel && (opt->mimicmodel != save->mimicmodel)) - free(opt->mimicmodel); - if (opt->adminauthuser && (opt->adminauthuser != save->adminauthuser)) - free(opt->adminauthuser); + if (opt->uampath) + free(opt->uampath); + if (opt->unixcodepage) + free(opt->unixcodepage); } -/* initialize options */ -void afp_options_init(struct afp_options *options) +void afp_options_duplicate(struct afp_options *options, const struct afp_options *soptions) { - memset(options, 0, sizeof(struct afp_options)); - options->connections = 20; - options->pidfile = _PATH_AFPDLOCK; - options->defaultvol.name = _PATH_AFPDDEFVOL; - options->systemvol.name = _PATH_AFPDSYSVOL; - options->configfile = _PATH_AFPDCONF; - options->sigconffile = _PATH_AFPDSIGCONF; - options->uuidconf = _PATH_AFPDUUIDCONF; - options->uampath = _PATH_AFPDUAMPATH; - options->uamlist = "uams_dhx.so,uams_dhx2.so"; - options->guest = "nobody"; - options->loginmesg = ""; - options->transports = AFPTRANS_TCP; /* TCP only */ - options->passwdfile = _PATH_AFPDPWFILE; - options->tickleval = 30; - options->timeout = 4; /* 4 tickles = 2 minutes */ - options->sleep = 10 * 60 * 2; /* 10 h in 30 seconds tick */ - options->disconnected = 10 * 60 * 2; /* 10 h in 30 seconds tick */ - options->server_notif = 1; - options->authprintdir = NULL; - options->signatureopt = "auto"; - options->umask = 0; -#ifdef ADMIN_GRP - options->admingid = 0; -#endif /* ADMIN_GRP */ - options->k5service = NULL; - options->k5realm = NULL; - options->k5keytab = NULL; - options->unixcharset = CH_UNIX; - options->unixcodepage = "LOCALE"; - options->maccharset = CH_MAC; - options->maccodepage = "MAC_ROMAN"; - options->volnamelen = 80; /* spec: 255, 10.1: 73, 10.4/10.5: 80 */ - options->ntdomain = NULL; - options->ntseparator = NULL; -#ifdef USE_SRVLOC - /* don't advertize slp by default */ - options->flags |= OPTION_NOSLP; -#endif - options->dircachesize = DEFAULT_MAX_DIRCACHE_SIZE; - options->flags |= OPTION_ACL2MACCESS; - options->flags |= OPTION_UUID; - options->tcp_sndbuf = 0; /* 0 means don't change OS default */ - options->tcp_rcvbuf = 0; /* 0 means don't change OS default */ - options->dsireadbuf = 12; - options->mimicmodel = NULL; - options->fce_fmodwait = 60; /* put fmod events 60 seconds on hold */ - options->adminauthuser = NULL; + memcpy(options, soptions, sizeof(struct afp_options)); + + options->pidfile = NULL; + options->uuidconf = NULL; + + options->configfile = strdup(options->configfile); + options->guest = strdup(options->guest); + options->loginmesg = strdup(options->loginmesg); + options->maccodepage = strdup(options->maccodepage); + options->passwdfile = strdup(options->passwdfile); + options->sigconffile = strdup(options->sigconffile); + options->signatureopt = strdup(options->signatureopt); + options->uamlist = strdup(options->uamlist); + options->uampath = strdup(options->uampath); + options->unixcodepage = strdup(options->unixcodepage); } -/* parse an afpd.conf line. i'm doing it this way because it's - * easy. it is, however, massively hokey. sample afpd.conf: - * server:AFPServer@zone -loginmesg "blah blah blah" -nodsi - * "private machine"@zone2 -noguest -port 11012 - * server2 -nocleartxt -nodsi - * - * NOTE: this ignores unknown options - */ -int afp_options_parseline(char *buf, struct afp_options *options) +#define MAXVAL +int afp_options_parse(AFPObj *AFPObj) { - char *c, *opt; - - /* handle server */ - if (*buf != '-' && (c = getoption(buf, NULL)) && (opt = strdup(c))) - options->server = opt; - - /* parse toggles */ - if (strstr(buf, " -nodebug")) - options->flags &= ~OPTION_DEBUG; -#ifdef USE_SRVLOC - if (strstr(buf, " -slp")) - options->flags &= ~OPTION_NOSLP; -#endif -#ifdef USE_ZEROCONF - if (strstr(buf, " -nozeroconf")) + dictionary *config = AFPObj->iniconfig; + struct afp_options *options = &AFPObj->options; + int i; + const char *p, *tmp; + char val[MAXVAL]; + + /* [Global] */ + + options->logconfig = iniparser_getstring(config, INISEC_GLOBAL, "loglevel", "default:note"); + options->logfile = iniparser_getstring(config, INISEC_GLOBAL, "logfile", NULL); + setuplog(logconfig, logfile); + + /* [AFP] "options" options wo values */ + options->flags |= OPTION_ACL2MACCESS | OPTION_UUID; + + p = iniparser_getstring(config, INISEC_AFP, "options", ""); + strcpy(val, " "); + strlcat(val, p, MAXVAL); + + if (strstr(val, " nozeroconf")) options->flags |= OPTION_NOZEROCONF; -#endif - if (strstr(buf, " -nouservolfirst")) - options->flags &= ~OPTION_USERVOLFIRST; - if (strstr(buf, " -uservolfirst")) - options->flags |= OPTION_USERVOLFIRST; - if (strstr(buf, " -nouservol")) - options->flags |= OPTION_NOUSERVOL; - if (strstr(buf, " -uservol")) - options->flags &= ~OPTION_NOUSERVOL; - if (strstr(buf, " -proxy")) - options->flags |= OPTION_PROXY; - if (strstr(buf, " -noicon")) - options->flags &= ~OPTION_CUSTOMICON; - if (strstr(buf, " -icon")) + if (strstr(val, " icon")) options->flags |= OPTION_CUSTOMICON; - if (strstr(buf, " -advertise_ssh")) + if (strstr(val, " noicon")) + options->flags &= ~OPTION_CUSTOMICON; + if (strstr(val, " advertise_ssh")) options->flags |= OPTION_ANNOUNCESSH; - if (strstr(buf, " -noacl2maccess")) + if (strstr(val, " noacl2maccess")) options->flags &= ~OPTION_ACL2MACCESS; - if (strstr(buf, " -keepsessions")) { - default_options.flags |= OPTION_KEEPSESSIONS; + if (strstr(val, " keepsessions")) options->flags |= OPTION_KEEPSESSIONS; - } - - /* passwd bits */ - if (strstr(buf, " -nosavepassword")) + if (strstr(val, " keepsessions")) + options->flags |= OPTION_CLOSEVOL; + if (strstr(val, " nosavepassword")) options->passwdbits |= PASSWD_NOSAVE; - if (strstr(buf, " -savepassword")) + if (strstr(val, " savepassword")) options->passwdbits &= ~PASSWD_NOSAVE; - if (strstr(buf, " -nosetpassword")) + if (strstr(val, " nosetpassword")) options->passwdbits &= ~PASSWD_SET; - if (strstr(buf, " -setpassword")) + if (strstr(val, " setpassword")) options->passwdbits |= PASSWD_SET; - - /* transports */ - if (strstr(buf, " -transall")) - options->transports = AFPTRANS_ALL; - if (strstr(buf, " -notransall")) - options->transports = AFPTRANS_NONE; - if (strstr(buf, " -tcp")) - options->transports |= AFPTRANS_TCP; - if (strstr(buf, " -notcp")) - options->transports &= ~AFPTRANS_TCP; - if (strstr(buf, " -ddp")) - options->transports |= AFPTRANS_DDP; - if (strstr(buf, " -noddp")) - options->transports &= ~AFPTRANS_DDP; - if (strstr(buf, "-client_polling")) + if (strstr(val, " client_polling")) options->server_notif = 0; - /* figure out options w/ values. currently, this will ignore the setting - * if memory is lacking. */ - - if ((c = getoption(buf, "-hostname"))) { - int len = strlen (c); - if (len <= MAXHOSTNAMELEN) { - memcpy(options->hostname, c, len); - options->hostname[len] = 0; - } - else - LOG(log_info, logtype_afpd, "WARNING: hostname %s is too long (%d)",c,len); - } - - if ((c = getoption(buf, "-defaultvol")) && (opt = strdup(c))) - options->defaultvol.name = opt; - if ((c = getoption(buf, "-systemvol")) && (opt = strdup(c))) - options->systemvol.name = opt; - if ((c = getoption(buf, "-loginmesg")) && (opt = strdup(c))) { - int i = 0, j = 0; - while (c[i]) { - if (c[i] != '\\') { - opt[j++] = c[i]; - } else { - i++; - if (c[i] == 'n') - opt[j++] = '\n'; - } - i++; - } - opt[j] = 0; - options->loginmesg = opt; - - } - if ((c = getoption(buf, "-guestname")) && (opt = strdup(c))) - options->guest = opt; - if ((c = getoption(buf, "-passwdfile")) && (opt = strdup(c))) - options->passwdfile = opt; - if ((c = getoption(buf, "-passwdminlen"))) - options->passwdminlen = MIN(1, atoi(c)); - if ((c = getoption(buf, "-loginmaxfail"))) - options->loginmaxfail = atoi(c); - if ((c = getoption(buf, "-tickleval"))) { - options->tickleval = atoi(c); - if (options->tickleval <= 0) { - options->tickleval = 30; - } - } - if ((c = getoption(buf, "-timeout"))) { - options->timeout = atoi(c); - if (options->timeout <= 0) { - options->timeout = 4; - } - } - - if ((c = getoption(buf, "-sleep"))) { - options->disconnected = options->sleep = atoi(c) * 120; - if (options->sleep <= 4) { - options->disconnected = options->sleep = 4; - } - } - - if ((c = getoption(buf, "-dsireadbuf"))) { - options->dsireadbuf = atoi(c); - if (options->dsireadbuf < 6) - options->dsireadbuf = 6; - } - - if ((c = getoption(buf, "-server_quantum"))) - options->server_quantum = strtoul(c, NULL, 0); - - if ((c = getoption(buf, "-volnamelen"))) { - options->volnamelen = atoi(c); - if (options->volnamelen < 8) { - options->volnamelen = 8; /* max mangled volname "???#FFFF" */ - } - if (options->volnamelen > 255) { - options->volnamelen = 255; /* AFP3 spec */ - } - } - - /* -[no]setuplog []*/ - c = buf; - /* Now THIS is hokey! Multiple occurrences are not supported by our current code, */ - /* so I have to loop myself. */ - while (NULL != (c = strstr(c, "-setuplog"))) { - char *optstr; - if ((optstr = getoption(c, "-setuplog"))) { - /* hokey2: options->logconfig must be converted to store an array of logstrings */ - if (options->logconfig) - free(options->logconfig); - options->logconfig = strdup(optstr); - setuplog(optstr); - c += sizeof("-setuplog"); - } + /* figure out options w values */ + + options->loginmesg = iniparser_getstring(config, INISEC_AFP, "loginmesg", ""); + options->guest = iniparser_getstring(config, INISEC_AFP, "guestname", "nobody"); + options->passwdfile = iniparser_getstring(config, INISEC_AFP, "passwdfile", _PATH_AFPDPWFILE); + options->uampath = iniparser_getstring(config, INISEC_AFP, "uampath", _PATH_AFPDUAMPATH); + options->uamlist = iniparser_getstring(config, INISEC_AFP, "uamlist", "uams_dhx.so,uams_dhx2.so"); + options->port = iniparser_getstring(config, INISEC_AFP, "port", "548"); + options->signatureopt = iniparser_getstring(config, INISEC_AFP, "signature", "auto"); + + options->connections = iniparser_getint (config, INISEC_AFP, "maxcon", 200); + options->passwdminlen = iniparser_getint (config, INISEC_AFP, "passwdminlen", 0); + options->tickleval = iniparser_getint (config, INISEC_AFP, "tickleval", 30); + options->timeout = iniparser_getint (config, INISEC_AFP, "timeout", 4); + options->dsireadbuf = iniparser_getint (config, INISEC_AFP, "dsireadbuf", 12); + options->server_quantum = iniparser_getint (config, INISEC_AFP, "server_quantum", DSI_SERVQUANT_DEF); + options->volnamelen = iniparser_getint (config, INISEC_AFP, "volnamelen", 80); + options->dircachesize = iniparser_getint (config, INISEC_AFP, "dircachesize", DEFAULT_MAX_DIRCACHE_SIZE); + options->tcp_sndbuf = iniparser_getint (config, INISEC_AFP, "tcpsndbuf", 0); + options->tcp_rcvbuf = iniparser_getint (config, INISEC_AFP, "tcprcvbuf", 0); + options->fce_fmodwait = iniparser_getint (config, INISEC_AFP, "fceholdfmod", 60); + options->sleep = iniparser_getint (config, INISEC_AFP, "sleep", 10) * 60 * 2; + options->disconnect = iniparser_getint (config, INISEC_AFP, "disconnect" 24) * 60 * 2; + + options->k5service = iniparser_getstringdup(config, INISEC_AFP, "k5service", NULL); + options->k5realm = iniparser_getstringdup(config, INISEC_AFP, "k5realm", NULL); + options->authprintdir = iniparser_getstringdup(config, INISEC_AFP, "authprintdir", NULL); + options->ipaddr = iniparser_getstringdup(config, INISEC_AFP, "ipaddr", NULL); + options->hostname = iniparser_getstringdup(config, INISEC_AFP, "hostname", NULL); + options->ntdomain = iniparser_getstringdup(config, INISEC_AFP, "ntdomain", NULL); + options->ntseparator = iniparser_getstringdup(config, INISEC_AFP, "ntseparator", NULL); + options->mimicmodel = iniparser_getstringdup(config, INISEC_AFP, "mimicmodel", NULL); + options->adminauthuser = iniparser_getstringdup(config, INISEC_AFP, "adminauthuser", NULL); + + if ((p = iniparser_getstring(config, INISEC_AFP, "k5keytab", NULL))) { + EC_NULL_LOG( options->k5keytab = malloc(strlen(p) + 14) ); + snprintf(options->k5keytab, strlen(p) + 14, "KRB5_KTNAME=%s", p); + putenv(options->k5keytab); } - if ((c = getoption(buf, "-unsetuplog"))) - unsetuplog(c); - #ifdef ADMIN_GRP - if ((c = getoption(buf, "-admingroup"))) { - struct group *gr = getgrnam(c); - if (gr != NULL) { - options->admingid = gr->gr_gid; - } + if ((p = iniparser_getstring(config, INISEC_AFP, "admingroup", NULL))) { + struct group *gr = getgrnam(p); + if (gr != NULL) + options->admingid = gr->gr_gid; } #endif /* ADMIN_GRP */ - if ((c = getoption(buf, "-k5service")) && (opt = strdup(c))) - options->k5service = opt; - if ((c = getoption(buf, "-k5realm")) && (opt = strdup(c))) - options->k5realm = opt; - if ((c = getoption(buf, "-k5keytab"))) { - if ( NULL == (options->k5keytab = (char *) malloc(sizeof(char)*(strlen(c)+14)) )) { - LOG(log_error, logtype_afpd, "malloc failed"); - exit(-1); - } - snprintf(options->k5keytab, strlen(c)+14, "KRB5_KTNAME=%s", c); - putenv(options->k5keytab); - /* setenv( "KRB5_KTNAME", c, 1 ); */ - } - if ((c = getoption(buf, "-authprintdir")) && (opt = strdup(c))) - options->authprintdir = opt; - if ((c = getoption(buf, "-uampath")) && (opt = strdup(c))) - options->uampath = opt; - if ((c = getoption(buf, "-uamlist")) && (opt = strdup(c))) - options->uamlist = opt; - - if ((c = getoption(buf, "-ipaddr"))) { -#if 0 - struct in_addr inaddr; - if (inet_aton(c, &inaddr) && (opt = strdup(c))) { - if (!gethostbyaddr((const char *) &inaddr, sizeof(inaddr), AF_INET)) - LOG(log_info, logtype_afpd, "WARNING: can't find %s", opt); - options->ipaddr = opt; - } - else { - LOG(log_error, logtype_afpd, "Error parsing -ipaddr, is %s in numbers-and-dots notation?", c); + p = iniparser_getstring(config, INISEC_AFP, "cnidserver", "localhost:4700"); + tmp = strrchr(p, ':'); + if (tmp) + *t = 0; + options->Cnid_srv = strdup(p); + if (tmp) + options->Cnid_port = strdup(tmp + 1); + LOG(log_debug, logtype_afpd, "CNID Server: %s:%s", options->Cnid_srv, options->Cnid_port); + + + if ((p = iniparser_getstring(config, INISEC_AFP, "fqdn", NULL))) { + /* do a little checking for the domain name. */ + tmp = strchr(c, ':'); + if (tmp) + *tmp = '\0'; + if (gethostbyname(p)) { + if (tmp) + *tmp = ':'; + if ((opt = strdup(p))) + options->fqdn = opt; + } else { + LOG(log_error, logtype_afpd, "error parsing -fqdn, gethostbyname failed for: %s", c); } -#endif - options->ipaddr = strdup(c); } - /* FIXME CNID Cnid_srv is a server attribute */ - if ((c = getoption(buf, "-cnidserver"))) { - char *p = strrchr(c, ':'); - if (p) - *p = 0; - Cnid_srv = strdup(c); - if (p) - Cnid_port = strdup(p + 1); - LOG(log_debug, logtype_afpd, "CNID Server: %s:%s", Cnid_srv, Cnid_port); + p = iniparser_getstring(config, INISEC_AFP, "unixcodepage", "LOCALE"); + if ((options->unixcharset = add_charset(p)) == (charset_t)-1) { + options->unixcharset = CH_UNIX; + LOG(log_warning, logtype_afpd, "Setting Unix codepage to '%s' failed", p); + } else { + options->unixcodepage = strdup(p); } - - if ((c = getoption(buf, "-port"))) - options->port = strdup(c); - if ((c = getoption(buf, "-signature")) && (opt = strdup(c))) - options->signatureopt = opt; - - /* do a little checking for the domain name. */ - if ((c = getoption(buf, "-fqdn"))) { - char *p = strchr(c, ':'); - if (p) - *p = '\0'; - if (gethostbyname(c)) { - if (p) - *p = ':'; - if ((opt = strdup(c))) - options->fqdn = opt; - } - else { - LOG(log_error, logtype_afpd, "error parsing -fqdn, gethostbyname failed for: %s", c); - } + + p = iniparser_getstring(config, INISEC_AFP, "maccodepage", "MAC_ROMAN"); + if ((options->maccharset = add_charset(p)) == (charset_t)-1) { + options->maccharset = CH_MAC; + LOG(log_warning, logtype_afpd, "Setting Unix codepage to '%s' failed", p); + } else { + options->maccharset = strdup(p); } - if ((c = getoption(buf, "-unixcodepage"))) { - if ((charset_t)-1 == ( options->unixcharset = add_charset(c)) ) { - options->unixcharset = CH_UNIX; - LOG(log_warning, logtype_afpd, "setting Unix codepage to '%s' failed", c); - } - else { - if ((opt = strdup(c))) - options->unixcodepage = opt; - } + if ((p = iniparser_getstring(config, INISEC_AFP, "fcelistener", NULL))) { + LOG(log_note, logtype_afpd, "Adding FCE listener: %s", p); + fce_add_udp_socket(p); } - - if ((c = getoption(buf, "-maccodepage"))) { - if ((charset_t)-1 == ( options->maccharset = add_charset(c)) ) { - options->maccharset = CH_MAC; - LOG(log_warning, logtype_afpd, "setting Mac codepage to '%s' failed", c); - } - else { - if ((opt = strdup(c))) - options->maccodepage = opt; - } + if ((p = iniparser_getstring(config, INISEC_AFP, "fcecoalesce", NULL))) { + LOG(log_note, logtype_afpd, "Fce coalesce: %s", p); + fce_set_coalesce(p); } - - if ((c = strstr(buf, "-closevol"))) { - options->closevol= 1; + if ((p = iniparser_getstring(config, INISEC_AFP, "fceevents", NULL))) { + LOG(log_note, logtype_afpd, "Fce events: %s", p); + fce_set_events(p); } - if ((c = getoption(buf, "-ntdomain")) && (opt = strdup(c))) - options->ntdomain = opt; - - if ((c = getoption(buf, "-ntseparator")) && (opt = strdup(c))) - options->ntseparator = opt; - - if ((c = getoption(buf, "-dircachesize"))) - options->dircachesize = atoi(c); - - if ((c = getoption(buf, "-tcpsndbuf"))) - options->tcp_sndbuf = atoi(c); - - if ((c = getoption(buf, "-tcprcvbuf"))) - options->tcp_rcvbuf = atoi(c); - - if ((c = getoption(buf, "-fcelistener"))) { - LOG(log_note, logtype_afpd, "Adding fce listener \"%s\"", c); - fce_add_udp_socket(c); - } - if ((c = getoption(buf, "-fcecoalesce"))) { - LOG(log_note, logtype_afpd, "Fce coalesce: %s", c); - fce_set_coalesce(c); - } - if ((c = getoption(buf, "-fceevents"))) { - LOG(log_note, logtype_afpd, "Fce events: %s", c); - fce_set_events(c); - } - - if ((c = getoption(buf, "-fceholdfmod"))) - options->fce_fmodwait = atoi(c); - - if ((c = getoption(buf, "-mimicmodel")) && (opt = strdup(c))) - options->mimicmodel = opt; - - if ((c = getoption(buf, "-adminauthuser")) && (opt = strdup(c))) - options->adminauthuser = opt; + /* Check for sane values */ + if (options->tickleval <= 0) + options->tickleval = 30; + if (options->timeout <= 0) + options->timeout = 4; + if (options->sleep <= 4) + options->disconnected = options->sleep = 4; + if (options->dsireadbuf < 6) + options->dsireadbuf = 6; + if (options->volnamelen < 8) + options->volnamelen = 8; /* max mangled volname "???#FFFF" */ + if (options->volnamelen > 255) + options->volnamelen = 255; /* AFP3 spec */ return 1; } @@ -577,13 +350,6 @@ static void show_version_extended(void ) { show_version( ); - printf( " SLP support:\t" ); -#ifdef USE_SRVLOC - puts( "Yes" ); -#else - puts( "No" ); -#endif - printf( " Zeroconf support:\t" ); #ifdef USE_ZEROCONF puts( "Yes" ); @@ -669,13 +435,13 @@ static void show_paths( void ) */ static void show_usage( char *name ) { - fprintf( stderr, "Usage:\t%s [-duptDTI] [-f defaultvolumes] [-s systemvolumes] [-n nbpname]\n", name ); + fprintf( stderr, "Usage:\t%s [-duptDTI] [-n nbpname]\n", name ); fprintf( stderr, "\t [-c maxconnections] [-g guest] [-P pidfile] [-S port] [-L message]\n" ); fprintf( stderr, "\t [-F configfile] [-U uams] [-m umask]\n" ); fprintf( stderr, "\t%s -h|-v|-V\n", name ); } -int afp_options_parse(int ac, char **av, struct afp_options *options) +int afp_options_parse_cmdline(int ac, char **av, struct afp_options *options) { extern char *optarg; extern int optind; @@ -683,105 +449,38 @@ int afp_options_parse(int ac, char **av, struct afp_options *options) char *p; char *tmp; /* Used for error checking the result of strtol */ int c, err = 0; + char buf[1024]; - if (gethostname(options->hostname, sizeof(options->hostname )) < 0 ) { + if (gethostname(buf, sizeof(buf)) < 0 ) { perror( "gethostname" ); return 0; } - if (NULL != ( p = strchr(options->hostname, '.' )) ) { + if (NULL != (p = strchr(buf, '.'))) *p = '\0'; - } - -#ifdef ultrix - if (NULL == ( p = strrchr( av[ 0 ], '/' )) ) { - p = av[ 0 ]; - } else { - p++; - } - openlog( p, LOG_PID ); /* ultrix only */ -#endif /* ultrix */ + options->hostname = strdup(buf); while (EOF != ( c = getopt( ac, av, OPTIONS )) ) { switch ( c ) { case 'd' : options->flags |= OPTION_DEBUG; break; - case 'n' : - options->server = optarg; - break; - case 'f' : - options->defaultvol.name = optarg; - break; - case 's' : - options->systemvol.name = optarg; - break; - case 'u' : - options->flags |= OPTION_USERVOLFIRST; - break; - case 'c' : - options->connections = atoi( optarg ); - break; - case 'g' : - options->guest = optarg; - break; - - case 'P' : - options->pidfile = optarg; - break; - - case 'p': - options->passwdbits |= PASSWD_NOSAVE; - break; - case 't': - options->passwdbits |= PASSWD_SET; - break; - - case 'D': - options->transports &= ~AFPTRANS_DDP; - break; - case 'S': - options->port = optarg; - break; - case 'T': - options->transports &= ~AFPTRANS_TCP; - break; - case 'L': - options->loginmesg = optarg; - break; case 'F': options->configfile = optarg; break; - case 'U': - options->uamlist = optarg; - break; case 'v': /* version */ show_version( ); puts( "" ); - show_paths( ); puts( "" ); + show_paths( ); puts( "" ); exit( 0 ); break; case 'V': /* extended version */ show_version_extended( ); puts( "" ); - show_paths( ); puts( "" ); + show_paths( ); puts( "" ); exit( 0 ); break; case 'h': /* usage */ show_usage( p ); exit( 0 ); break; - case 'I': - options->flags |= OPTION_CUSTOMICON; - break; - case 'm': - options->umask = strtoul(optarg, &tmp, 8); - if ((options->umask > 0777)) { - fprintf(stderr, "%s: out of range umask setting provided\n", p); - err++; - } - if (tmp[0] != '\0') { - fprintf(stderr, "%s: invalid characters in umask setting provided\n", p); - err++; - } - break; default : err++; } diff --git a/etc/afpd/auth.c b/etc/afpd/auth.c index 60a5b69c..d6382c84 100644 --- a/etc/afpd/auth.c +++ b/etc/afpd/auth.c @@ -142,7 +142,7 @@ static int send_reply(const AFPObj *obj, const int err) if ((err == AFP_OK) || (err == AFPERR_AUTHCONT)) return err; - obj->reply(obj->handle, err); + obj->reply(obj->dsi, err); obj->exit(0); return AFP_OK; @@ -364,7 +364,7 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen) { uint32_t data; - DSI *dsi = (DSI *)AFPobj->handle; + DSI *dsi = (DSI *)AFPobj->dsi; *rbuflen = 0; ibuf += 2; @@ -557,7 +557,7 @@ int afp_getsession( /* ---------------------- */ int afp_disconnect(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { - DSI *dsi = (DSI *)obj->handle; + DSI *dsi = (DSI *)obj->dsi; uint16_t type; uint32_t tklen; pid_t token; @@ -868,7 +868,7 @@ int afp_logincont(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { - DSI *dsi = (DSI *)(obj->handle); + DSI *dsi = (DSI *)(obj->dsi); LOG(log_note, logtype_afpd, "AFP logout by %s", obj->username); of_close_all_forks(); diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index adf6bbb3..c03f0769 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -205,8 +205,8 @@ int afp_addicon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t addicon_err: if ( cc < 0 ) { if (obj->proto == AFPPROTO_DSI) { - dsi_writeinit(obj->handle, rbuf, buflen); - dsi_writeflush(obj->handle); + dsi_writeinit(obj->dsi, rbuf, buflen); + dsi_writeflush(obj->dsi); } return cc; } @@ -214,7 +214,7 @@ addicon_err: switch (obj->proto) { case AFPPROTO_DSI: { - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; iovcnt = dsi_writeinit(dsi, rbuf, buflen); @@ -442,7 +442,7 @@ int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t rc = min( bsize, rsize ); if ((obj->proto == AFPPROTO_DSI) && (buflen < rc)) { - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; struct stat st; off_t size; diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 9bef65b0..8e0ba732 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -852,7 +852,7 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si /* dsi can stream requests. we can only do this if we're not checking * for an end-of-line character. oh well. */ if ((obj->proto == AFPPROTO_DSI) && (*rbuflen < reqcount) && !nlmask) { - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; off_t size; /* reqcount isn't always truthful. we need to deal with that. */ @@ -1195,7 +1195,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s switch (obj->proto) { case AFPPROTO_DSI: { - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; /* find out what we have already and write it out. */ cc = dsi_writeinit(dsi, rbuf, *rbuflen); @@ -1265,8 +1265,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s afp_write_err: if (obj->proto == AFPPROTO_DSI) { - dsi_writeinit(obj->handle, rbuf, *rbuflen); - dsi_writeflush(obj->handle); + dsi_writeinit(obj->dsi, rbuf, *rbuflen); + dsi_writeflush(obj->dsi); } if (err != AFP_OK) { *rbuflen = 0; diff --git a/etc/afpd/main.c b/etc/afpd/main.c index c549fa09..43b8d080 100644 --- a/etc/afpd/main.c +++ b/etc/afpd/main.c @@ -38,22 +38,12 @@ #include "uam_auth.h" #include "afp_zeroconf.h" -#ifdef TRU64 -#include -#include -#include - -static int argc = 0; -static char **argv = NULL; -#endif /* TRU64 */ - #define AFP_LISTENERS 32 #define FDSET_SAFETY 5 -unsigned char nologin = 0; -struct afp_options default_options; +unsigned char nologin = 0; -static AFPConfig *configs; +static AFPObj AFPObj; static server_child *server_children; static sig_atomic_t reloadconfig = 0; static sig_atomic_t gotsigchld = 0; @@ -65,14 +55,6 @@ static int fdset_size; /* current allocated size */ static int fdset_used; /* number of used elements */ static int disasociated_ipc_fd; /* disasociated sessions uses this fd for IPC */ -#ifdef TRU64 -void afp_get_cmdline( int *ac, char ***av) -{ - *ac = argc; - *av = argv; -} -#endif /* TRU64 */ - /* This is registered with atexit() */ static void afp_exit(void) { @@ -85,25 +67,23 @@ static void afp_exit(void) /* ------------------ initialize fd set we are waiting for. */ -static void fd_set_listening_sockets(void) +static void fd_set_listening_sockets(const AFPObj *config) { - AFPConfig *config; + const DSI *dsi; - for (config = configs; config; config = config->next) { - if (config->fd < 0) /* for proxies */ - continue; - fdset_add_fd(default_options.connections + AFP_LISTENERS + FDSET_SAFETY, + for (dsi = config->dsi; dsi; dsi = dsi->next) { + fdset_add_fd(config->options.connections + AFP_LISTENERS + FDSET_SAFETY, &fdset, &polldata, &fdset_used, &fdset_size, - config->fd, + dsi->serversock, LISTEN_FD, - config); + dsi); } - if (default_options.flags & OPTION_KEEPSESSIONS) - fdset_add_fd(default_options.connections + AFP_LISTENERS + FDSET_SAFETY, + if (config->options.flags & OPTION_KEEPSESSIONS) + fdset_add_fd(config->options.connections + AFP_LISTENERS + FDSET_SAFETY, &fdset, &polldata, &fdset_used, @@ -113,25 +93,21 @@ static void fd_set_listening_sockets(void) NULL); } -static void fd_reset_listening_sockets(void) +static void fd_reset_listening_sockets(const AFPObj *config) { - AFPConfig *config; + const DSI *dsi; - for (config = configs; config; config = config->next) { - if (config->fd < 0) /* for proxies */ - continue; - fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, config->fd); + for (dsi = config->dsi; dsi; dsi = dsi->next) { + fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, dsi->serversock); } - if (default_options.flags & OPTION_KEEPSESSIONS) + if (config->options.flags & OPTION_KEEPSESSIONS) fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd); } /* ------------------ */ static void afp_goaway(int sig) { - AFPConfig *config; - switch( sig ) { case SIGTERM: @@ -152,10 +128,8 @@ static void afp_goaway(int sig) if (server_children) server_child_kill(server_children, CHILD_DSIFORK, sig); - for (config = configs; config; config = config->next) - if (config->server_cleanup) - config->server_cleanup(config); - server_unlock(default_options.pidfile); + dsi_cleanup(AFPObj); + server_unlock(AFPObj->options.pidfile); exit(0); break; @@ -238,22 +212,16 @@ static int setlimits(void) int main(int ac, char **av) { - AFPConfig *config; fd_set rfds; void *ipc; struct sigaction sv; sigset_t sigs; int ret; - -#ifdef TRU64 - argc = ac; - argv = av; - set_auth_parameters( ac, av ); -#endif /* TRU64 */ + struct afp_options default_options = {0}; /* Parse argv args and initialize default options */ afp_options_init(&default_options); - if (!afp_options_parse(ac, av, &default_options)) + if (!afp_options_parse_cmdline(ac, av, &default_options)) exit(EXITERR_CONF); if (check_lockfile("afpd", default_options.pidfile) != 0) @@ -380,7 +348,7 @@ int main(int ac, char **av) sigaddset(&sigs, SIGCHLD); pthread_sigmask(SIG_BLOCK, &sigs, NULL); - if (!(configs = configinit(&default_options))) { + if (!(AFPObj = configinit(&default_options))) { LOG(log_error, logtype_afpd, "main: no servers configured"); exit(EXITERR_CONF); } @@ -391,12 +359,12 @@ int main(int ac, char **av) /* watch atp, dsi sockets and ipc parent/child file descriptor. */ - if (default_options.flags & OPTION_KEEPSESSIONS) { + if (AFPObj.options.flags & OPTION_KEEPSESSIONS) { LOG(log_note, logtype_afpd, "Activating continous service"); disasociated_ipc_fd = ipc_server_uds(_PATH_AFP_IPC); } - fd_set_listening_sockets(); + fd_set_listening_sockets(&AFPObj); /* set limits */ (void)setlimits(); @@ -428,22 +396,20 @@ int main(int ac, char **av) if (reloadconfig) { nologin++; auth_unload(); - fd_reset_listening_sockets(); + fd_reset_listening_sockets(&AFPObj); LOG(log_info, logtype_afpd, "re-reading configuration file"); - for (config = configs; config; config = config->next) - if (config->server_cleanup) - config->server_cleanup(config); + dsi_cleanup(&AFPObj); /* configfree close atp socket used for DDP tickle, there's an issue * with atp tid. */ - configfree(configs, NULL); - if (!(configs = configinit(&default_options))) { + configfree(&AFPObj); + if (!(AFPObj = configinit(&default_options))) { LOG(log_error, logtype_afpd, "config re-read: no servers configured"); exit(EXITERR_CONF); } - fd_set_listening_sockets(); + fd_set_listening_sockets(&AFPObj); nologin = 0; reloadconfig = 0; @@ -466,11 +432,9 @@ int main(int ac, char **av) switch (polldata[i].fdtype) { case LISTEN_FD: - config = (AFPConfig *)polldata[i].data; - /* config->server_start is afp_config.c:dsi_start() for DSI */ - if (child = config->server_start(config, configs, server_children)) { + if (child = dsi_start(AFPObj, (DSI *)polldata[i].data, server_children)) { /* Add IPC fd to select fd set */ - fdset_add_fd(default_options.connections + AFP_LISTENERS + FDSET_SAFETY, + fdset_add_fd(AFPObj.options.connections + AFP_LISTENERS + FDSET_SAFETY, &fdset, &polldata, &fdset_used, @@ -489,7 +453,7 @@ int main(int ac, char **av) fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]); close(child->ipc_fds[0]); child->ipc_fds[0] = -1; - if ((default_options.flags & OPTION_KEEPSESSIONS) && child->disasociated) { + if ((AFPObj.options.flags & OPTION_KEEPSESSIONS) && child->disasociated) { LOG(log_note, logtype_afpd, "main: removing reattached child[%u]", child->pid); server_child_remove(server_children, CHILD_DSIFORK, child->pid); } @@ -514,7 +478,7 @@ int main(int ac, char **av) break; } child->disasociated = 1; - fdset_add_fd(default_options.connections + AFP_LISTENERS + FDSET_SAFETY, + fdset_add_fd(AFPObj.options.connections + AFP_LISTENERS + FDSET_SAFETY, &fdset, &polldata, &fdset_used, diff --git a/etc/afpd/messages.c b/etc/afpd/messages.c index ba72e382..cd3f32f7 100644 --- a/etc/afpd/messages.c +++ b/etc/afpd/messages.c @@ -44,7 +44,7 @@ void readmessage(AFPObj *obj) uid_t euid; uint32_t maxmsgsize; - maxmsgsize = (obj->proto == AFPPROTO_DSI)?MIN(MAX(((DSI*)obj->handle)->attn_quantum, MAXMESGSIZE),MAXPATHLEN):MAXMESGSIZE; + maxmsgsize = (obj->proto == AFPPROTO_DSI)?MIN(MAX(((DSI*)obj->dsi)->attn_quantum, MAXMESGSIZE),MAXPATHLEN):MAXMESGSIZE; i=0; /* Construct file name SERVERTEXT/message.[pid] */ @@ -121,7 +121,7 @@ int afp_getsrvrmesg(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, siz *rbuflen = 0; - msgsize = (obj->proto == AFPPROTO_DSI)?MAX(((DSI*)obj->handle)->attn_quantum, MAXMESGSIZE):MAXMESGSIZE; + msgsize = (obj->proto == AFPPROTO_DSI)?MAX(((DSI*)obj->dsi)->attn_quantum, MAXMESGSIZE):MAXMESGSIZE; memcpy(&type, ibuf + 2, sizeof(type)); memcpy(&bitmap, ibuf + 4, sizeof(bitmap)); diff --git a/etc/afpd/status.c b/etc/afpd/status.c index 897af8dc..4aa134e9 100644 --- a/etc/afpd/status.c +++ b/etc/afpd/status.c @@ -428,7 +428,7 @@ void status_init(AFPConfig *dsiconfig, if (dsiconfig) { status = dsiconfig->status; maxstatuslen=sizeof(dsiconfig->status); - dsi = dsiconfig->obj.handle; + dsi = dsiconfig->obj.dsi; if (dsi->server.ss_family == AF_INET) { /* IPv4 */ const struct sockaddr_in *sa4 = (struct sockaddr_in *)&dsi->server; ipok = sa4->sin_addr.s_addr ? 1 : 0; diff --git a/etc/afpd/uam.c b/etc/afpd/uam.c index de0fae7c..8adfb3bb 100644 --- a/etc/afpd/uam.c +++ b/etc/afpd/uam.c @@ -311,7 +311,7 @@ int uam_random_string (AFPObj *obj, char *buf, int len) if (gettimeofday(&tv, &tz) < 0) return -1; - srandom(tv.tv_sec + (unsigned long) obj + (unsigned long) obj->handle); + srandom(tv.tv_sec + (unsigned long) obj + (unsigned long) obj->dsi); for (i = 0; i < len; i += sizeof(result)) { result = random(); memcpy(buf + i, &result, sizeof(result)); @@ -364,11 +364,6 @@ int uam_afpserver_option(void *private, const int what, void *option, *len = sizeof(obj->options.passwdminlen); break; - case UAM_PASSWD_MAXFAIL: - *((int *) option) = obj->options.loginmaxfail; - *len = sizeof(obj->options.loginmaxfail); - break; - case UAM_PASSWD_EXPIRETIME: /* not implemented */ default: return -1; @@ -401,7 +396,7 @@ int uam_afpserver_option(void *private, const int what, void *option, case UAM_OPTION_CLIENTNAME: { - struct DSI *dsi = obj->handle; + struct DSI *dsi = obj->dsi; const struct sockaddr *sa; static char hbuf[NI_MAXHOST]; @@ -466,15 +461,15 @@ int uam_afp_read(void *handle, char *buf, size_t *buflen, if (!obj) return AFPERR_PARAM; - len = dsi_writeinit(obj->handle, buf, *buflen); + len = dsi_writeinit(obj->dsi, buf, *buflen); if (!len || ((len = action(handle, buf, len)) < 0)) { - dsi_writeflush(obj->handle); + dsi_writeflush(obj->dsi); goto uam_afp_read_err; } - while ((len = (dsi_write(obj->handle, buf, *buflen)))) { + while ((len = (dsi_write(obj->dsi, buf, *buflen)))) { if ((len = action(handle, buf, len)) < 0) { - dsi_writeflush(obj->handle); + dsi_writeflush(obj->dsi); goto uam_afp_read_err; } } diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index f5964499..d15e9a46 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -237,7 +237,7 @@ static char *volxlate(AFPObj *obj, } else if (is_var(p, "$c")) { if (afpmaster && xlatevolname) return NULL; - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; len = sprintf(dest, "%s:%u", getip_string((struct sockaddr *)&dsi->client), getip_port((struct sockaddr *)&dsi->client)); @@ -264,7 +264,7 @@ static char *volxlate(AFPObj *obj, } else if (is_var(p, "$i")) { if (afpmaster && xlatevolname) return NULL; - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; q = getip_string((struct sockaddr *)&dsi->client); } else if (is_var(p, "$s")) { if (obj->Obj) @@ -880,7 +880,7 @@ static int hostaccessvol(int type, const char *volname, const char *args, const { int mask_int; char buf[MAXPATHLEN + 1], *p, *b; - DSI *dsi = obj->handle; + DSI *dsi = obj->dsi; struct sockaddr_storage client; if (!args) @@ -2494,7 +2494,7 @@ int pollvoltime(AFPObj *obj) if ( (vol->v_flags & AFPVOL_OPEN) && vol->v_mtime + 30 < tv.tv_sec) { if ( !stat( vol->v_path, &st ) && vol->v_mtime != st.st_mtime ) { vol->v_mtime = st.st_mtime; - if (!obj->attention(obj->handle, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED)) + if (!obj->attention(obj->dsi, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED)) return -1; return 1; } @@ -2525,7 +2525,7 @@ void setvoltime(AFPObj *obj, struct vol *vol) * AFP 3.2 and above clients seem to be ok without so many notification */ if (afp_version < 32 && obj->options.server_notif) { - obj->attention(obj->handle, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED); + obj->attention(obj->dsi, AFPATTN_NOTIFY | AFPATTN_VOLCHANGED); } } } diff --git a/include/atalk/afp.h b/include/atalk/afp.h index c8137136..76315aa4 100644 --- a/include/atalk/afp.h +++ b/include/atalk/afp.h @@ -33,15 +33,6 @@ typedef uint16_t AFPUserBytes; #define AFPPROTO_ASP 1 #define AFPPROTO_DSI 2 -/* actual transports. the DSI ones (tcp right now) need to be - * kept in sync w/ . - * convention: AFPTRANS_* = (1 << DSI_*) - */ -#define AFPTRANS_NONE 0 -#define AFPTRANS_DDP (1 << 0) -#define AFPTRANS_TCP (1 << 1) -#define AFPTRANS_ALL (AFPTRANS_DDP | AFPTRANS_TCP) - /* server flags */ #define AFPSRVRINFO_COPY (1<<0) /* supports copyfile */ #define AFPSRVRINFO_PASSWD (1<<1) /* supports change password */ diff --git a/include/atalk/dictionary.h b/include/atalk/dictionary.h index c7d17909..0d6eb677 100644 --- a/include/atalk/dictionary.h +++ b/include/atalk/dictionary.h @@ -60,115 +60,12 @@ typedef struct _dictionary_ { Function prototypes ---------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------*/ -/** - @brief Compute the hash key for a string. - @param key Character string to use for key. - @return 1 unsigned int on at least 32 bits. - - This hash function has been taken from an Article in Dr Dobbs Journal. - This is normally a collision-free function, distributing keys evenly. - The key is stored anyway in the struct so that collision can be avoided - by comparing the key itself in last resort. - */ -/*--------------------------------------------------------------------------*/ -unsigned dictionary_hash(char * key); - -/*-------------------------------------------------------------------------*/ -/** - @brief Create a new dictionary object. - @param size Optional initial size of the dictionary. - @return 1 newly allocated dictionary objet. - - This function allocates a new dictionary object of given size and returns - it. If you do not know in advance (roughly) the number of entries in the - dictionary, give size=0. - */ -/*--------------------------------------------------------------------------*/ -dictionary * dictionary_new(int size); - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete a dictionary object - @param d dictionary object to deallocate. - @return void - - Deallocate a dictionary object and all memory associated to it. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_del(dictionary * vd); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get a value from a dictionary. - @param d dictionary object to search. - @param key Key to look for in the dictionary. - @param def Default value to return if key not found. - @return 1 pointer to internally allocated character string. - - This function locates a key in a dictionary and returns a pointer to its - value, or the passed 'def' pointer if no such key can be found in - dictionary. The returned character pointer points to data internal to the - dictionary object, you should not try to free it or modify it. - */ -/*--------------------------------------------------------------------------*/ -char * dictionary_get(dictionary * d, char * key, char * def); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Set a value in a dictionary. - @param d dictionary object to modify. - @param key Key to modify or add. - @param val Value to add. - @return int 0 if Ok, anything else otherwise - - If the given key is found in the dictionary, the associated value is - replaced by the provided one. If the key cannot be found in the - dictionary, it is added to it. - - It is Ok to provide a NULL value for val, but NULL values for the dictionary - or the key are considered as errors: the function will return immediately - in such a case. - - Notice that if you dictionary_set a variable to NULL, a call to - dictionary_get will return a NULL value: the variable will be found, and - its value (NULL) is returned. In other words, setting the variable - content to NULL is equivalent to deleting the variable from the - dictionary. It is not possible (in this implementation) to have a key in - the dictionary without value. - - This function returns non-zero in case of failure. - */ -/*--------------------------------------------------------------------------*/ -int dictionary_set(dictionary * vd, char * key, char * val); - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete a key in a dictionary - @param d dictionary object to modify. - @param key Key to remove. - @return void - - This function deletes a key in a dictionary. Nothing is done if the - key cannot be found. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_unset(dictionary * d, char * key); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Dump a dictionary to an opened file pointer. - @param d Dictionary to dump - @param f Opened file pointer. - @return void - - Dumps a dictionary onto an opened file pointer. Key pairs are printed out - as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as - output file pointers. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_dump(dictionary * d, FILE * out); +unsigned dictionary_hash (char * key); +dictionary *dictionary_new (int size); +void dictionary_del (dictionary * vd); +char *dictionary_get (dictionary * d, char *section, char * key, char * def); +int dictionary_set (dictionary * vd, char *section, char * key, char * val); +void dictionary_unset (dictionary * d, char *section, char * key); +void dictionary_dump (dictionary * d, FILE * out); #endif diff --git a/include/atalk/dsi.h b/include/atalk/dsi.h index de7464a5..6f7cddd0 100644 --- a/include/atalk/dsi.h +++ b/include/atalk/dsi.h @@ -3,7 +3,7 @@ * All rights reserved. */ -#ifndef _ATALK_DSI_H +#ifndef _ATALK_DSI_H #define _ATALK_DSI_H #include @@ -18,90 +18,86 @@ #include /* What a DSI packet looks like: - 0 32 - |-------------------------------| - |flags |command| requestID | - |-------------------------------| - |error code/enclosed data offset| - |-------------------------------| - |total data length | - |-------------------------------| - |reserved field | - |-------------------------------| - - CONVENTION: anything with a dsi_ prefix is kept in network byte order. + 0 32 + |-------------------------------| + |flags |command| requestID | + |-------------------------------| + |error code/enclosed data offset| + |-------------------------------| + |total data length | + |-------------------------------| + |reserved field | + |-------------------------------| + + CONVENTION: anything with a dsi_ prefix is kept in network byte order. */ -/* these need to be kept in sync w/ AFPTRANS_* in . +/* these need to be kept in sync w/ AFPTRANS_* in . * convention: AFPTRANS_* = (1 << DSI_*) */ typedef enum { - DSI_MIN = 1, - DSI_TCPIP = 1, - DSI_MAX = 1 + DSI_MIN = 1, + DSI_TCPIP = 1, + DSI_MAX = 1 } dsi_proto; #define DSI_BLOCKSIZ 16 struct dsi_block { - uint8_t dsi_flags; /* packet type: request or reply */ - uint8_t dsi_command; /* command */ - uint16_t dsi_requestID; /* request ID */ - uint32_t dsi_code; /* error code or data offset */ - uint32_t dsi_len; /* total data length */ - uint32_t dsi_reserved; /* reserved field */ + uint8_t dsi_flags; /* packet type: request or reply */ + uint8_t dsi_command; /* command */ + uint16_t dsi_requestID; /* request ID */ + uint32_t dsi_code; /* error code or data offset */ + uint32_t dsi_len; /* total data length */ + uint32_t dsi_reserved; /* reserved field */ }; -#define DSI_CMDSIZ 8192 +#define DSI_CMDSIZ 8192 #define DSI_DATASIZ 8192 /* child and parent processes might interpret a couple of these * differently. */ typedef struct DSI { - AFPObj *AFPobj; - dsi_proto protocol; - struct dsi_block header; - struct sockaddr_storage server, client; - struct itimerval timer; - int tickle; /* tickle count */ - int in_write; /* in the middle of writing multiple packets, - signal handlers can't write to the socket */ - int msg_request; /* pending message to the client */ - int down_request; /* pending SIGUSR1 down in 5 mn */ - - uint32_t attn_quantum, datasize, server_quantum; - uint16_t serverID, clientID; - char *status; - uint8_t commands[DSI_CMDSIZ], data[DSI_DATASIZ]; - size_t statuslen; - size_t datalen, cmdlen; - off_t read_count, write_count; - uint32_t flags; /* DSI flags like DSI_SLEEPING, DSI_DISCONNECTED */ - const char *program; - int socket, serversock; - - /* protocol specific open/close, send/receive - * send/receive fill in the header and use dsi->commands. - * write/read just write/read data */ - pid_t (*proto_open)(struct DSI *); - void (*proto_close)(struct DSI *); - - /* url registered with slpd */ -#ifdef USE_SRVLOC - char srvloc_url[512]; -#endif + DSI *next; /* multiple listening addresses */ + AFPObj *AFPobj; + struct dsi_block header; + struct sockaddr_storage server, client; + struct itimerval timer; + int tickle; /* tickle count */ + int in_write; /* in the middle of writing multiple packets, + signal handlers can't write to the socket */ + int msg_request; /* pending message to the client */ + int down_request; /* pending SIGUSR1 down in 5 mn */ + + uint32_t attn_quantum, datasize, server_quantum; + uint16_t serverID, clientID; + char *status; + uint8_t commands[DSI_CMDSIZ], data[DSI_DATASIZ]; + size_t statuslen; + size_t datalen, cmdlen; + off_t read_count, write_count; + uint32_t flags; /* DSI flags like DSI_SLEEPING, DSI_DISCONNECTED */ + const char *program; + int socket; /* AFP session socket */ + int serversock; /* listening socket */ + + /* DSI readahead buffer used for buffered reads in dsi_peek */ + size_t dsireadbuf; /* size of the DSI readahead buffer used in dsi_peek() */ + char *buffer; /* buffer start */ + char *start; /* current buffer head */ + char *eof; /* end of currently used buffer */ + char *end; #ifdef USE_ZEROCONF - char *bonjourname; /* server name as UTF8 maxlen MAXINSTANCENAMELEN */ - int zeroconf_registered; + char *bonjourname; /* server name as UTF8 maxlen MAXINSTANCENAMELEN */ + int zeroconf_registered; #endif - /* DSI readahead buffer used for buffered reads in dsi_peek */ - size_t dsireadbuf; /* size of the DSI readahead buffer used in dsi_peek() */ - char *buffer; - char *start; - char *eof; - char *end; + /* protocol specific open/close, send/receive + * send/receive fill in the header and use dsi->commands. + * write/read just write/read data */ + pid_t (*proto_open)(struct DSI *); + void (*proto_close)(struct DSI *); } DSI; - + /* DSI flags */ #define DSIFL_REQUEST 0x00 #define DSIFL_REPLY 0x01 @@ -123,17 +119,17 @@ typedef struct DSI { #define DSIFUNC_MAX 8 /* largest command */ /* DSI Error codes: most of these aren't used. */ -#define DSIERR_OK 0x0000 -#define DSIERR_BADVERS 0xfbd6 -#define DSIERR_BUFSMALL 0xfbd5 -#define DSIERR_NOSESS 0xfbd4 -#define DSIERR_NOSERV 0xfbd3 -#define DSIERR_PARM 0xfbd2 -#define DSIERR_SERVBUSY 0xfbd1 -#define DSIERR_SESSCLOS 0xfbd0 -#define DSIERR_SIZERR 0xfbcf -#define DSIERR_TOOMANY 0xfbce -#define DSIERR_NOACK 0xfbcd +#define DSIERR_OK 0x0000 +#define DSIERR_BADVERS 0xfbd6 +#define DSIERR_BUFSMALL 0xfbd5 +#define DSIERR_NOSESS 0xfbd4 +#define DSIERR_NOSERV 0xfbd3 +#define DSIERR_PARM 0xfbd2 +#define DSIERR_SERVBUSY 0xfbd1 +#define DSIERR_SESSCLOS 0xfbd0 +#define DSIERR_SIZERR 0xfbcf +#define DSIERR_TOOMANY 0xfbce +#define DSIERR_NOACK 0xfbcd /* server and client quanta */ #define DSI_DEFQUANT 2 /* default attention quantum size */ @@ -161,10 +157,10 @@ typedef struct DSI { /* basic initialization: dsi_init.c */ extern DSI *dsi_init (const dsi_proto /*protocol*/, - const char * /*program*/, - const char * /*host*/, const char * /*address*/, - const char * /*port*/, const int /*proxy*/, - const uint32_t /* server quantum */); + const char * /*program*/, + const char * /*host*/, const char * /*address*/, + const char * /*port*/, const int /*proxy*/, + const uint32_t /* server quantum */); extern void dsi_setstatus (DSI *, char *, const size_t); /* in dsi_getsess.c */ @@ -200,15 +196,15 @@ extern void dsi_writeflush (DSI *); /* client reads -- dsi_read.c */ extern ssize_t dsi_readinit (DSI *, void *, const size_t, const size_t, - const int); + const int); extern ssize_t dsi_read (DSI *, void *, const size_t); extern void dsi_readdone (DSI *); /* some useful macros */ #define dsi_serverID(x) ((x)->serverID++) -#define dsi_send(x) do { \ - (x)->header.dsi_len = htonl((x)->cmdlen); \ - dsi_stream_send((x), (x)->commands, (x)->cmdlen); \ -} while (0) +#define dsi_send(x) do { \ + (x)->header.dsi_len = htonl((x)->cmdlen); \ + dsi_stream_send((x), (x)->commands, (x)->cmdlen); \ + } while (0) #endif /* atalk/dsi.h */ diff --git a/include/atalk/globals.h b/include/atalk/globals.h index b65eeba1..62e754a4 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -17,11 +17,11 @@ #include /* this isn't header-protected under ultrix */ #endif /* HAVE_NETDB_H */ -#include #include #include #include #include +#include /* #define DOSFILELEN 12 */ /* Type1, DOS-compat*/ #define MACFILELEN 31 /* Type2, HFS-compat */ @@ -33,17 +33,24 @@ #define MAXUSERLEN 256 #define OPTION_DEBUG (1 << 0) -#define OPTION_USERVOLFIRST (1 << 1) -#define OPTION_NOUSERVOL (1 << 2) -#define OPTION_PROXY (1 << 3) +#define OPTION_CLOSEVOL (1 << 1) #define OPTION_CUSTOMICON (1 << 4) -#define OPTION_NOSLP (1 << 5) #define OPTION_ANNOUNCESSH (1 << 6) #define OPTION_UUID (1 << 7) #define OPTION_ACL2MACCESS (1 << 8) #define OPTION_NOZEROCONF (1 << 9) #define OPTION_KEEPSESSIONS (1 << 10) /* preserve sessions across master afpd restart with SIGQUIT */ +/********************************************************************************************** + * Ini config sections + **********************************************************************************************/ + +#define INISEC_GLOBAL "General" +#define INISEC_AFP "AFP" + +struct DSI; +#define AFPOBJ_TMPSIZ (MAXPATHLEN) + /* a couple of these options could get stuck in unions to save * space. */ struct afp_volume_name { @@ -54,22 +61,27 @@ struct afp_volume_name { }; struct afp_options { - int connections, transports, tickleval, timeout, server_notif, flags, dircachesize; + int connections; /* Maximum number of possible AFP connections */ + int tickleval; + int timeout; + int server_notif; + int flags; + int dircachesize; int sleep; /* Maximum time allowed to sleep (in tickles) */ int disconnected; /* Maximum time in disconnected state (in tickles) */ int fce_fmodwait; /* number of seconds FCE file mod events are put on hold */ unsigned int tcp_sndbuf, tcp_rcvbuf; - unsigned char passwdbits, passwdminlen, loginmaxfail; + unsigned char passwdbits, passwdminlen; uint32_t server_quantum; int dsireadbuf; /* scale factor for sizefof(dsi->buffer) = server_quantum * dsireadbuf */ - char hostname[MAXHOSTNAMELEN + 1], *server, *ipaddr, *port, *configfile; + char *hostname; + char *ipaddr, *port; + char *Cnid_srv, *Cnid_port; + char *configfile; char *uampath, *fqdn; char *pidfile; char *sigconffile; char *uuidconf; - struct afp_volume_name defaultvol, systemvol, uservol; - int closevol; - char *guest, *loginmesg, *keyfile, *passwdfile; char *uamlist; char *authprintdir; @@ -84,33 +96,33 @@ struct afp_options { gid_t admingid; #endif /* ADMIN_GRP */ int volnamelen; - /* default value for winbind authentication */ char *ntdomain, *ntseparator; char *logconfig; - + char *logfile; char *mimicmodel; char *adminauthuser; }; -#define AFPOBJ_TMPSIZ (MAXPATHLEN) -typedef struct _AFPObj { - int proto; - unsigned long servernum; - void *handle; /* either (DSI *) or (ASP *) */ - void *config; +typedef struct AFPObj { + int statuslen; + char status[1400]; + const void *signature; + struct DSI *dsi; struct afp_options options; - char *Obj, *Type, *Zone; + const dictionary *iniconfig; char username[MAXUSERLEN]; - void (*logout)(void), (*exit)(int); - int (*reply)(void *, int); - int (*attention)(void *, AFPUserBytes); /* to prevent confusion, only use these in afp_* calls */ char oldtmp[AFPOBJ_TMPSIZ + 1], newtmp[AFPOBJ_TMPSIZ + 1]; void *uam_cookie; /* cookie for uams */ struct session_info sinfo; uid_t uid; /* client running user id */ int ipc_fd; /* anonymous PF_UNIX socket for IPC with afpd parent */ + /* Functions */ + void (*logout)(void); + void (*exit)(int); + int (*reply)(void *, int); + int (*attention)(void *, AFPUserBytes); } AFPObj; /* typedef for AFP functions handlers */ @@ -129,8 +141,8 @@ extern const char *Cnid_port; extern int get_afp_errno (const int param); extern void afp_options_init (struct afp_options *); -extern int afp_options_parse (int, char **, struct afp_options *); -extern int afp_options_parseline (char *, struct afp_options *); +extern int afp_options_parse_cmdline (int, char **, struct afp_options *); +extern int afp_options_parseline (char *, struct afp_options *); extern void afp_options_free (struct afp_options *, const struct afp_options *); extern void setmessage (const char *); diff --git a/include/atalk/iniparser.h b/include/atalk/iniparser.h index e3468b2c..6436e4e0 100644 --- a/include/atalk/iniparser.h +++ b/include/atalk/iniparser.h @@ -34,240 +34,19 @@ #include "dictionary.h" -/*-------------------------------------------------------------------------*/ -/** - @brief Get number of sections in a dictionary - @param d Dictionary to examine - @return int Number of sections found in dictionary - - This function returns the number of sections found in a dictionary. - The test to recognize sections is done on the string stored in the - dictionary: a section name is given as "section" whereas a key is - stored as "section:key", thus the test looks for entries that do not - contain a colon. - - This clearly fails in the case a section name contains a colon, but - this should simply be avoided. - - This function returns -1 in case of error. - */ -/*--------------------------------------------------------------------------*/ - -int iniparser_getnsec(dictionary * d); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Get name for section n in a dictionary. - @param d Dictionary to examine - @param n Section number (from 0 to nsec-1). - @return Pointer to char string - - This function locates the n-th section in a dictionary and returns - its name as a pointer to a string statically allocated inside the - dictionary. Do not free or modify the returned string! - - This function returns NULL in case of error. - */ -/*--------------------------------------------------------------------------*/ - -char * iniparser_getsecname(dictionary * d, int n); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Save a dictionary to a loadable ini file - @param d Dictionary to dump - @param f Opened file pointer to dump to - @return void - - This function dumps a given dictionary into a loadable ini file. - It is Ok to specify @c stderr or @c stdout as output files. - */ -/*--------------------------------------------------------------------------*/ - -void iniparser_dump_ini(dictionary * d, FILE * f); - -/*-------------------------------------------------------------------------*/ -/** - @brief Dump a dictionary to an opened file pointer. - @param d Dictionary to dump. - @param f Opened file pointer to dump to. - @return void - - This function prints out the contents of a dictionary, one element by - line, onto the provided file pointer. It is OK to specify @c stderr - or @c stdout as output files. This function is meant for debugging - purposes mostly. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_dump(dictionary * d, FILE * f); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key - @param d Dictionary to search - @param key Key string to look for - @param def Default value to return if key not found. - @return pointer to statically allocated character string - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the pointer passed as 'def' is returned. - The returned char pointer is pointing to a string allocated in - the dictionary, do not free or modify it. - */ -/*--------------------------------------------------------------------------*/ -char * iniparser_getstring(dictionary * d, char * key, char * def); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to an int - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return integer - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - - Supported values for integers include the usual C notation - so decimal, octal (starting with 0) and hexadecimal (starting with 0x) - are supported. Examples: - - - "42" -> 42 - - "042" -> 34 (octal -> decimal) - - "0x42" -> 66 (hexa -> decimal) - - Warning: the conversion may overflow in various ways. Conversion is - totally outsourced to strtol(), see the associated man page for overflow - handling. - - Credits: Thanks to A. Becker for suggesting strtol() - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getint(dictionary * d, char * key, int notfound); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to a double - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return double - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - */ -/*--------------------------------------------------------------------------*/ -double iniparser_getdouble(dictionary * d, char * key, double notfound); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to a boolean - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return integer - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - - A true boolean is found if one of the following is matched: - - - A string starting with 'y' - - A string starting with 'Y' - - A string starting with 't' - - A string starting with 'T' - - A string starting with '1' - - A false boolean is found if one of the following is matched: - - - A string starting with 'n' - - A string starting with 'N' - - A string starting with 'f' - - A string starting with 'F' - - A string starting with '0' - - The notfound value returned if no boolean is identified, does not - necessarily have to be 0 or 1. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getboolean(dictionary * d, char * key, int notfound); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Set an entry in a dictionary. - @param ini Dictionary to modify. - @param entry Entry to modify (entry name) - @param val New value to associate to the entry. - @return int 0 if Ok, -1 otherwise. - - If the given entry can be found in the dictionary, it is modified to - contain the provided value. If it cannot be found, -1 is returned. - It is Ok to set val to NULL. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_set(dictionary * ini, char * entry, char * val); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete an entry in a dictionary - @param ini Dictionary to modify - @param entry Entry to delete (entry name) - @return void - - If the given entry can be found, it is deleted from the dictionary. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_unset(dictionary * ini, char * entry); - -/*-------------------------------------------------------------------------*/ -/** - @brief Finds out if a given entry exists in a dictionary - @param ini Dictionary to search - @param entry Name of the entry to look for - @return integer 1 if entry exists, 0 otherwise - - Finds out if a given entry exists in the dictionary. Since sections - are stored as keys with NULL associated values, this is the only way - of querying for the presence of sections in a dictionary. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_find_entry(dictionary * ini, char * entry) ; - -/*-------------------------------------------------------------------------*/ -/** - @brief Parse an ini file and return an allocated dictionary object - @param ininame Name of the ini file to read. - @return Pointer to newly allocated dictionary - - This is the parser for ini files. This function is called, providing - the name of the file to be read. It returns a dictionary object that - should not be accessed directly, but through accessor functions - instead. - - The returned dictionary must be freed using iniparser_freedict(). - */ -/*--------------------------------------------------------------------------*/ -dictionary * iniparser_load(char * ininame); - -/*-------------------------------------------------------------------------*/ -/** - @brief Free all memory associated to an ini dictionary - @param d Dictionary to free - @return void - - Free all memory associated to an ini dictionary. - It is mandatory to call this function before the dictionary object - gets out of the current context. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_freedict(dictionary * d); +int iniparser_getnsec(dictionary * d); +char *iniparser_getsecname(dictionary * d, int n); +void iniparser_dump_ini(dictionary * d, FILE * f); +void iniparser_dump(dictionary * d, FILE * f); +char *iniparser_getstring(dictionary * d, char *section, char * key, char * def); +char *iniparser_getstringdup(dictionary * d, char *section, char * key, char * def); +int iniparser_getint(dictionary * d, char *section, char * key, int notfound); +double iniparser_getdouble(dictionary * d, char *section, char * key, double notfound); +int iniparser_getboolean(dictionary * d, char *section, char * key, int notfound); +int iniparser_set(dictionary * ini, char *section, char * key, char * val); +void iniparser_unset(dictionary * ini, char *section, char * key); +int iniparser_find_entry(dictionary * ini, char * entry) ; +dictionary *iniparser_load(char * ininame); +void iniparser_freedict(dictionary * d); #endif diff --git a/include/atalk/ldapconfig.h b/include/atalk/ldapconfig.h index 5a5b6570..76f5561b 100644 --- a/include/atalk/ldapconfig.h +++ b/include/atalk/ldapconfig.h @@ -3,8 +3,10 @@ #ifndef LDAPCONFIG_H #define LDAPCONFIG_H +#include + /* One function does the whole job */ -extern int acl_ldap_readconfig(char *name); +extern int acl_ldap_readconfig(dictionary *iniconfig); /* These are the prefvalues */ extern char *ldap_server; diff --git a/include/atalk/logger.h b/include/atalk/logger.h index 0c6e7d85..cf67bcad 100644 --- a/include/atalk/logger.h +++ b/include/atalk/logger.h @@ -159,28 +159,7 @@ extern UAM_MODULE_EXPORT logtype_conf_t type_configs[logtype_end_of_list_marker] Global function decarations ========================================================================= */ -/* */ -void log_init(void); - -/* Setup the level and type of log that will be logged for file loggging */ -void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logtype); - -/* Setup the level and type of log that will be logged to syslog. */ -void syslog_setup(int loglevel, enum logtypes logtype, - int display_options, int facility); - -/* This gets called e.g. from afpd.conf parsing code with a string like: */ -/* "default log_maxdebug /var/log/afpd.log" */ -void setuplog(const char *logstr); - -/* This gets called e.g. from afpd.conf parsing code with a string like: */ -/* "default dummyname" */ -void unsetuplog(const char *logstr); - -/* finish up and close the logs */ -void log_close(void); - -/* This function sets up the ProcessName */ +void setuplog(const char *loglevel, const char *logfile); void set_processname(const char *processname); /* LOG macro func no.1: log the message to file */ @@ -193,9 +172,6 @@ UAM_MODULE_EXPORT void make_log_entry(enum loglevels loglevel, enum logtypes lo * We choose the verbose form in favor of the obfuscated ones, its easier * to parse for human beings and facilitates expanding the macro for * inline checks for debug levels. - * - * How to properly enclose multistatement macros: - * http://en.wikipedia.org/wiki/C_macro#Multiple_statements */ #define LOG_MAX log_info diff --git a/include/atalk/uam.h b/include/atalk/uam.h index d0499c6f..72207f1f 100644 --- a/include/atalk/uam.h +++ b/include/atalk/uam.h @@ -52,7 +52,6 @@ * get back the corresponding option. not all of these are implemented. */ #define UAM_PASSWD_FILENAME (1 << 0) #define UAM_PASSWD_MINLENGTH (1 << 1) -#define UAM_PASSWD_MAXFAIL (1 << 2) /* not implemented yet. */ #define UAM_PASSWD_EXPIRETIME (1 << 3) /* not implemented yet. */ /* max lenght of username */ diff --git a/libatalk/acl/ldap_config.c b/libatalk/acl/ldap_config.c index da37fb97..d719cafd 100644 --- a/libatalk/acl/ldap_config.c +++ b/libatalk/acl/ldap_config.c @@ -27,97 +27,44 @@ #include #include +#include -#define LINESIZE 1024 - -/* Parse one line. Return result in pref and val */ -static int getpref(char *buf, char **R_pref, char **R_val) -{ - char *p, *pref, *val; - - /* a little pre-processing to get rid of spaces and end-of-lines */ - p = buf; - while (p && isspace(*p)) - p++; - if (!p || (*p == '\0')) - return -1; - - if ((val = strchr(p, '=')) == NULL) - return -1; - while ((*val == '=') || (*val == ' ')) - val++; - if ((val = strtok(val, " \n")) == NULL) - return -1; - if ((val = strdup(val)) == NULL) - return -1; - if ((pref = strtok(p, " =")) == NULL) - return -1; - - *R_pref = pref; - *R_val = val; - return 0; -} - -/* Parse the afp_ldap.conf file */ -int acl_ldap_readconfig(char *name) +int acl_ldap_readconfig(dictionary *iniconfig) { int i, j; - FILE *f; - char buf[LINESIZE]; - char *pref, *val; + char *val; - f = fopen(name,"r"); - if (!f) { - perror("fopen"); - return -1; + i = 0; + /* now see if its a correct pref */ + for (i = 0; ldap_prefs[i].name != NULL; i++) { + if ((val = iniparser_getstring(ldap_prefs[i].name)) != NULL) { + /* ok, found a valid pref */ + + /* check if we have pre-defined values */ + if (ldap_prefs[i].intfromarray == 0) { + /* no, its just a string */ + ldap_prefs[i].valid = 0; + if (ldap_prefs[i].strorint) + /* store as int */ + *((int *)(ldap_prefs[i].pref)) = atoi(val); + else + /* store string as string */ + *((char **)(ldap_prefs[i].pref)) = val; + } else { + /* ok, we have string to int mapping for this pref + eg. "none", "simple", "sasl" map to 0, 128, 129 */ + for (j = 0; prefs_array[j].pref != NULL; j++) { + if ((strcmp(prefs_array[j].pref, ldap_prefs[i].name) == 0) + && (strcmp(prefs_array[j].valuestring, val) == 0)) { + ldap_prefs[i].valid = 0; + *((int *)(ldap_prefs[i].pref)) = prefs_array[j].value; + break; + } + } + } + } } - while (!feof(f)) { - /* read a line from file */ - if (!fgets(buf, LINESIZE, f) || buf[0] == '#') - continue; - - /* parse and return pref and value */ - if ((getpref(buf, &pref, &val)) != 0) - continue; - - i = 0; - /* now see if its a correct pref */ - while(ldap_prefs[i].pref != NULL) { - if ((strcmp(ldap_prefs[i].name, pref)) == 0) { - /* ok, found a valid pref */ - - /* check if we have pre-defined values */ - if (0 == ldap_prefs[i].intfromarray) { - /* no, its just a string */ - ldap_prefs[i].valid = 0; - if (0 == ldap_prefs[i].strorint) - /* store string as string */ - *((char **)(ldap_prefs[i].pref)) = val; - else - /* store as int */ - *((int *)(ldap_prefs[i].pref)) = atoi(val); - } else { - /* ok, we have string to int mapping for this pref - eg. "none", "simple", "sasl" map to 0, 128, 129 */ - j = 0; - while(prefs_array[j].pref != NULL) { - if (((strcmp(prefs_array[j].pref, pref)) == 0) && - ((strcmp(prefs_array[j].valuestring, val)) == 0)) { - ldap_prefs[i].valid = 0; - *((int *)(ldap_prefs[i].pref)) = prefs_array[j].value; - } - j++; - } /* while j*/ - } /* if else 0 == ldap_prefs*/ - break; - } /* if strcmp */ - i++; - } /* while i */ - if (ldap_prefs[i].pref == NULL) - LOG(log_error, logtype_afpd,"afp_ldap.conf: Unknown option: \"%s\"", pref); - } /* EOF */ - /* check if the config is sane and complete */ i = 0; ldap_config_valid = 1; diff --git a/libatalk/dsi/dsi_opensess.c b/libatalk/dsi/dsi_opensess.c index e074a112..d01e64c4 100644 --- a/libatalk/dsi/dsi_opensess.c +++ b/libatalk/dsi/dsi_opensess.c @@ -18,16 +18,14 @@ static void dsi_init_buffer(DSI *dsi) { - size_t quantum = dsi->server_quantum ? dsi->server_quantum : DSI_SERVQUANT_DEF; - /* default is 12 * 300k = 3,6 MB (Apr 2011) */ - if ((dsi->buffer = malloc(dsi->dsireadbuf * quantum)) == NULL) { + if ((dsi->buffer = malloc(dsi->dsireadbuf * dsi->server_quantum)) == NULL) { LOG(log_error, logtype_dsi, "dsi_init_buffer: OOM"); AFP_PANIC("OOM in dsi_init_buffer"); } dsi->start = dsi->buffer; dsi->eof = dsi->buffer; - dsi->end = dsi->buffer + (dsi->dsireadbuf * quantum); + dsi->end = dsi->buffer + (dsi->dsireadbuf * dsi->server_quantum); } /* OpenSession. set up the connection */ diff --git a/libatalk/iniparser/dictionary.c b/libatalk/iniparser/dictionary.c index b7c9ebf1..6ba08358 100644 --- a/libatalk/iniparser/dictionary.c +++ b/libatalk/iniparser/dictionary.c @@ -19,7 +19,8 @@ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ -#include "dictionary.h" +#include +#include #include #include @@ -39,6 +40,20 @@ Private functions ---------------------------------------------------------------------------*/ +#define MAXKEYSIZE 1024 +static char *makekey(const char *section, const char *entry) +{ + static char buf[MAXKEYSIZE]; + + strlcpy(buf, section, MAXKEYSIZE); + if (entry) { + strlcat(buf, ":", MAXKEYSIZE); + strlcat(buf, entry, MAXKEYSIZE); + } + + return buf; +} + /* Doubles the allocated size associated to a pointer */ /* 'size' is the current allocated size. */ static void * mem_double(void * ptr, int size) @@ -178,19 +193,19 @@ void dictionary_del(dictionary * d) dictionary object, you should not try to free it or modify it. */ /*--------------------------------------------------------------------------*/ -char * dictionary_get(dictionary * d, char * key, char * def) +char * dictionary_get(dictionary * d, char *section, char * key, char * def) { unsigned hash ; int i ; - hash = dictionary_hash(key); + hash = dictionary_hash(makekey(section, key)); for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; /* Compare hash */ if (hash==d->hash[i]) { /* Compare string, to avoid hash collisions */ - if (!strcmp(key, d->key[i])) { + if (!strcmp(makekey(section, key), d->key[i])) { return d->val[i] ; } } @@ -224,7 +239,7 @@ char * dictionary_get(dictionary * d, char * key, char * def) This function returns non-zero in case of failure. */ /*--------------------------------------------------------------------------*/ -int dictionary_set(dictionary * d, char * key, char * val) +int dictionary_set(dictionary * d, char *section, char * key, char * val) { int i ; unsigned hash ; @@ -232,14 +247,14 @@ int dictionary_set(dictionary * d, char * key, char * val) if (d==NULL || key==NULL) return -1 ; /* Compute hash for this key */ - hash = dictionary_hash(key) ; + hash = dictionary_hash(makekey(section, key)); /* Find if value is already in dictionary */ if (d->n>0) { for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; if (hash==d->hash[i]) { /* Same hash value */ - if (!strcmp(key, d->key[i])) { /* Same key */ + if (!strcmp(makekey(section, key), d->key[i])) { /* Same key */ /* Found a value: modify and return */ if (d->val[i]!=NULL) free(d->val[i]); @@ -274,7 +289,7 @@ int dictionary_set(dictionary * d, char * key, char * val) } } /* Copy key */ - d->key[i] = xstrdup(key); + d->key[i] = xstrdup(makekey(section, key)); d->val[i] = val ? xstrdup(val) : NULL ; d->hash[i] = hash; d->n ++ ; @@ -292,7 +307,7 @@ int dictionary_set(dictionary * d, char * key, char * val) key cannot be found. */ /*--------------------------------------------------------------------------*/ -void dictionary_unset(dictionary * d, char * key) +void dictionary_unset(dictionary * d, char *section, char * key) { unsigned hash ; int i ; @@ -301,14 +316,14 @@ void dictionary_unset(dictionary * d, char * key) return; } - hash = dictionary_hash(key); + hash = dictionary_hash(makekey(section, key)); for (i=0 ; isize ; i++) { if (d->key[i]==NULL) continue ; /* Compare hash */ if (hash==d->hash[i]) { /* Compare string, to avoid hash collisions */ - if (!strcmp(key, d->key[i])) { + if (!strcmp(makekey(section, key), d->key[i])) { /* Found key */ break ; } @@ -359,47 +374,3 @@ void dictionary_dump(dictionary * d, FILE * out) } return ; } - - -/* Test code */ -#ifdef TESTDIC -#define NVALS 20000 -int main(int argc, char *argv[]) -{ - dictionary * d ; - char * val ; - int i ; - char cval[90] ; - - /* Allocate dictionary */ - printf("allocating...\n"); - d = dictionary_new(0); - - /* Set values in dictionary */ - printf("setting %d values...\n", NVALS); - for (i=0 ; in != 0) { - printf("error deleting values\n"); - } - printf("deallocating...\n"); - dictionary_del(d); - return 0 ; -} -#endif -/* vim: set ts=4 et sw=4 tw=75 */ diff --git a/libatalk/iniparser/iniparser.c b/libatalk/iniparser/iniparser.c index 096120e4..c1f5cc61 100644 --- a/libatalk/iniparser/iniparser.c +++ b/libatalk/iniparser/iniparser.c @@ -36,36 +36,6 @@ typedef enum _line_status_ { LINE_VALUE } line_status ; -/*-------------------------------------------------------------------------*/ -/** - @brief Convert a string to lowercase. - @param s String to convert. - @return ptr to statically allocated string. - - This function returns a pointer to a statically allocated string - containing a lowercased version of the input string. Do not free - or modify the returned string! Since the returned string is statically - allocated, it will be modified at each function call (not re-entrant). - */ -/*--------------------------------------------------------------------------*/ -static char * strlwc(char * s) -{ - return s; - - static char l[ASCIILINESZ+1]; - int i ; - - if (s==NULL) return NULL ; - memset(l, 0, ASCIILINESZ+1); - i=0 ; - while (s[i] && i= num_logtype_strings) { - return; - } - - /* Parse loglevel */ - if (loglevel == NULL) { - levelnum = 0; - } else { - for(levelnum=1; levelnum < num_loglevel_strings; levelnum++) { - if (strcasecmp(loglevel, arr_loglevel_strings[levelnum]) == 0) - break; - } - if (levelnum >= num_loglevel_strings) { - return; - } - } - - /* is this a syslog setup or a filelog setup ? */ - if (filename == NULL) { - /* must be syslog */ - syslog_setup(levelnum, - typenum, - logoption_ndelay | logoption_pid, - logfacility_daemon); - } else { - /* this must be a filelog */ - log_setup(filename, levelnum, typenum); - } - - return; -} - static void generate_message_details(char *message_details_buffer, int message_details_buffer_length, int display_options, @@ -279,11 +229,20 @@ static int get_syslog_equivalent(enum loglevels loglevel) } } -/* ========================================================================= - Global function definitions - ========================================================================= */ +/* Called by the LOG macro for syslog messages */ +static void make_syslog_entry(enum loglevels loglevel, enum logtypes logtype _U_, char *message) +{ + if ( !log_config.syslog_opened ) { + openlog(log_config.processname, + log_config.syslog_display_options, + log_config.syslog_facility); + log_config.syslog_opened = true; + } + + syslog(get_syslog_equivalent(loglevel), "%s", message); +} -void log_init(void) +static void log_init(void) { syslog_setup(log_info, logtype_default, @@ -291,7 +250,7 @@ void log_init(void) logfacility_daemon); } -void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logtype) +static void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logtype) { uid_t process_uid; @@ -407,7 +366,7 @@ void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logt } /* Setup syslog logging */ -void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility) +static void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility) { /* * FIXME: @@ -440,10 +399,60 @@ void syslog_setup(int loglevel, enum logtypes logtype, int display_options, int arr_loglevel_strings[loglevel]); } -void log_close(void) +/* + * If filename == NULL its for syslog logging, otherwise its for file-logging. + * "unsetuplog" calls with loglevel == NULL. + * loglevel == NULL means: + * if logtype == default + * disable logging + * else + * set to default logging + */ +static void setuplog_internal(const char *loglevel, const char *logtype, const char *filename) { + unsigned int typenum, levelnum; + + /* Parse logtype */ + for( typenum=0; typenum < num_logtype_strings; typenum++) { + if (strcasecmp(logtype, arr_logtype_strings[typenum]) == 0) + break; + } + if (typenum >= num_logtype_strings) { + return; + } + + /* Parse loglevel */ + if (loglevel == NULL) { + levelnum = 0; + } else { + for(levelnum=1; levelnum < num_loglevel_strings; levelnum++) { + if (strcasecmp(loglevel, arr_loglevel_strings[levelnum]) == 0) + break; + } + if (levelnum >= num_loglevel_strings) { + return; + } + } + + /* is this a syslog setup or a filelog setup ? */ + if (filename == NULL) { + /* must be syslog */ + syslog_setup(levelnum, + typenum, + logoption_ndelay | logoption_pid, + logfacility_daemon); + } else { + /* this must be a filelog */ + log_setup(filename, levelnum, typenum); + } + + return; } +/* ========================================================================= + Global function definitions + ========================================================================= */ + /* This function sets up the processname */ void set_processname(const char *processname) { @@ -451,19 +460,6 @@ void set_processname(const char *processname) log_config.processname[15] = 0; } -/* Called by the LOG macro for syslog messages */ -static void make_syslog_entry(enum loglevels loglevel, enum logtypes logtype _U_, char *message) -{ - if ( !log_config.syslog_opened ) { - openlog(log_config.processname, - log_config.syslog_display_options, - log_config.syslog_facility); - log_config.syslog_opened = true; - } - - syslog(get_syslog_equivalent(loglevel), "%s", message); -} - /* ------------------------------------------------------------------------- make_log_entry has 1 main flaws: The message in its entirity, must fit into the tempbuffer. @@ -619,57 +615,34 @@ exit: inlog = 0; } - -void setuplog(const char *logstr) +void setuplog(const char *logstr, const char *logfile) { - char *ptr, *ptrbak, *logtype, *loglevel = NULL, *filename = NULL; - ptr = strdup(logstr); - ptrbak = ptr; + char *ptr, *save; + char *logtype, *loglevel; + char c; - /* logtype */ - logtype = ptr; + save = ptr = strdup(logstr); - /* get loglevel */ - ptr = strpbrk(ptr, " \t"); - if (ptr) { - *ptr++ = 0; + while (*ptr) { while (*ptr && isspace(*ptr)) ptr++; - loglevel = ptr; - /* get filename */ - ptr = strpbrk(ptr, " \t"); - if (ptr) { - *ptr++ = 0; - while (*ptr && isspace(*ptr)) - ptr++; - } - filename = ptr; - if (filename && *filename == 0) - filename = NULL; - } + logtype = ptr; + ptr = strpbrk(ptr, ":"); + if (!ptr) + break; + *ptr = 0; - /* finally call setuplog, filename can be NULL */ - setuplog_internal(loglevel, logtype, filename); + ptr++; + loglevel = ptr; + while (*ptr && !isspace(*ptr)) + ptr++; + c = *ptr; + *ptr = 0; + setuplog_internal(loglevel, logtype, filename); + *ptr = c; + } - free(ptrbak); + free(save); } -void unsetuplog(const char *logstr) -{ - char *str, *logtype, *filename; - - str = strdup(logstr); - - /* logtype */ - logtype = str; - - /* get filename, can be NULL */ - strtok(str, " \t"); - filename = strtok(NULL, " \t"); - - /* finally call setuplog, filename can be NULL */ - setuplog_internal(NULL, str, filename); - - free(str); -} diff --git a/macros/srvloc.m4 b/macros/srvloc.m4 deleted file mode 100644 index 99f24f4b..00000000 --- a/macros/srvloc.m4 +++ /dev/null @@ -1,75 +0,0 @@ -dnl Check for optional server location protocol support (used by MacOS X) - -AC_DEFUN([AC_NETATALK_SRVLOC], [ - - SLP_LIBS="" - SLP_CFLAGS="" - found_slp=no - srvlocdir="" - - AC_ARG_ENABLE(srvloc, - [ --enable-srvloc[[=DIR]] enable Server Location Protocol (SLP) support], - [srvloc=$enableval], - [srvloc=no] - ) - - dnl make sure atalk_libname is defined beforehand - [[ -n "$atalk_libname" ]] || AC_MSG_ERROR([internal error, atalk_libname undefined]) - - if test "x$srvloc" != "xno"; then - - savedcppflags="$CPPFLAGS" - savedldflags="$LDFLAGS" - if test "x$srvloc" = "xyes" ; then - srvlocdir="/usr" - else - srvlocdir="$srvloc" - fi - CPPFLAGS="$CPPFLAGS -I$srvlocdir/include" - LDFLAGS="$LDFLAGS -L$srvlocdir/$atalk_libname" - - AC_MSG_CHECKING([for slp.h]) - AC_TRY_CPP([#include ], - [ - AC_MSG_RESULT([yes]) - found_slp=yes - ], - [ - AC_MSG_RESULT([no]) - ] - ) - - if test "x$found_slp" = "xyes"; then - AC_CHECK_LIB(slp, SLPOpen, [ - SLP_LIBS="-L$srvlocdir/$atalk_libname -lslp" - SLP_CFLAGS="-I$srvlocdir/include" - ],[ - AC_MSG_RESULT([no]) - found_slp=no - ]) - fi - - CPPFLAGS="$savedcppflags" - LDFLAGS="$savedldflags" - fi - - netatalk_cv_srvloc=no - AC_MSG_CHECKING([whether to enable srvloc (SLP) support]) - if test "x$found_slp" = "xyes"; then - AC_MSG_RESULT([yes]) - AC_DEFINE(USE_SRVLOC, 1, [Define to enable SLP support]) - netatalk_cv_srvloc=yes - else - AC_MSG_RESULT([no]) - if test "x$srvloc" != "xno" -a "x$srvloc" != "xyes"; then - AC_MSG_ERROR([SLP installation not found]) - fi - fi - - - - LIB_REMOVE_USR_LIB(SLP_LIBS) - CFLAGS_REMOVE_USR_INCLUDE(SLP_CFLAGS) - AC_SUBST(SLP_LIBS) - AC_SUBST(SLP_CFLAGS) -]) -- 2.39.2