-
- /* the master loaded the volumes for zeroconf, get rid of that */
- 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;
-#ifndef NO_DDP
- char *Obj, *Type = "", *Zone = "";
-#endif
-
- /* 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';
-
-#ifndef NO_DDP
- /* Add ZONE, */
- if (nbp_name(options->server, &Obj, &Type, &Zone )) {
- LOG(log_error, logtype_afpd, "srvloc_encode: can't parse %s", options->server );
- }
- else {
- snprintf( buf+i, sizeof(buf)-i-1 ,"&ZONE=%s", Zone);
- }
-#endif
- 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 */
-}
-
-#ifndef NO_DDP
-static void asp_cleanup(const AFPConfig *config)
-{
- /* we need to stop tickle handler */
- asp_stop_tickle();
- nbp_unrgstr(config->obj.Obj, config->obj.Type, config->obj.Zone,
- &config->obj.options.ddpaddr);
-}
-
-/* these two are almost identical. it should be possible to collapse them
- * into one with minimal junk. */
-static int asp_start(AFPConfig *config, AFPConfig *configs,
- server_child *server_children)
-{
- ASP asp;
-
- if (!(asp = asp_getsession(config->obj.handle, server_children,
- config->obj.options.tickleval))) {
- LOG(log_error, logtype_afpd, "main: asp_getsession: %s", strerror(errno) );
- exit( EXITERR_CLNT );
- }
-
- if (asp->child) {
- configfree(configs, config); /* free a bunch of stuff */
- afp_over_asp(&config->obj);
- exit (0);
- }
-
- return 0;
-}
-#endif /* no afp/asp */
-
-static afp_child_t *dsi_start(AFPConfig *config, AFPConfig *configs,
- server_child *server_children)
-{
- DSI *dsi = config->obj.handle;
- afp_child_t *child = NULL;
-
- if (!(child = dsi_getsession(dsi,
- server_children,
- config->obj.options.tickleval))) {
- LOG(log_error, logtype_afpd, "dsi_start: session error: %s", strerror(errno));
- return NULL;
- }
-
- /* we've forked. */
- if (parent_or_child == 1) {
- configfree(configs, config);
- config->obj.ipc_fd = child->ipc_fds[1];
- close(child->ipc_fds[0]); /* Close parent IPC fd */
- free(child);
- afp_over_dsi(&config->obj); /* start a session */
- exit (0);
- }
-
- return child;
-}
-
-#ifndef NO_DDP
-static AFPConfig *ASPConfigInit(const struct afp_options *options,
- unsigned char *refcount)
-{
- AFPConfig *config;
- ATP atp;
- ASP asp;
- char *Obj, *Type = "AFPServer", *Zone = "*";
- char *convname = NULL;
-
- if ((config = (AFPConfig *) calloc(1, sizeof(AFPConfig))) == NULL)
- return NULL;
-
- if ((atp = atp_open(ATADDR_ANYPORT, &options->ddpaddr)) == NULL) {
- LOG(log_error, logtype_afpd, "main: atp_open: %s", strerror(errno) );
- free(config);
- return NULL;
- }
-
- if ((asp = asp_init( atp )) == NULL) {
- LOG(log_error, logtype_afpd, "main: asp_init: %s", strerror(errno) );
- atp_close(atp);
- free(config);
- return NULL;
- }
-
- /* register asp server */
- Obj = (char *) options->hostname;
- if (options->server && (size_t)-1 ==(convert_string_allocate( options->unixcharset, options->maccharset,
- options->server, strlen(options->server), &convname)) ) {
- if ((convname = strdup(options->server)) == NULL ) {
- LOG(log_error, logtype_afpd, "malloc: %s", strerror(errno) );
- goto serv_free_return;
- }
- }
-
- if (nbp_name(convname, &Obj, &Type, &Zone )) {
- LOG(log_error, logtype_afpd, "main: can't parse %s", options->server );
- goto serv_free_return;
- }
- if (convname)
- free (convname);
-
- /* dup Obj, Type and Zone as they get assigned to a single internal
- * buffer by nbp_name */
- if ((config->obj.Obj = strdup(Obj)) == NULL)
- goto serv_free_return;
-
- if ((config->obj.Type = strdup(Type)) == NULL) {
- free(config->obj.Obj);
- goto serv_free_return;
- }
-
- if ((config->obj.Zone = strdup(Zone)) == NULL) {
- free(config->obj.Obj);
- free(config->obj.Type);
- goto serv_free_return;
- }
-
- /* make sure we're not registered */
- nbp_unrgstr(Obj, Type, Zone, &options->ddpaddr);
- if (nbp_rgstr( atp_sockaddr( atp ), Obj, Type, Zone ) < 0 ) {
- LOG(log_error, logtype_afpd, "Can't register %s:%s@%s", Obj, Type, Zone );
- free(config->obj.Obj);
- free(config->obj.Type);
- free(config->obj.Zone);
- goto serv_free_return;