From: didg Date: Mon, 26 May 2003 11:17:25 +0000 (+0000) Subject: change SIGHUP and SIGUSR1, SIGHUP reload config files, Volumes file are reloaded... X-Git-Tag: netatalk-2-0-alpha1~177 X-Git-Url: https://arthur.barton.de/gitweb/?a=commitdiff_plain;h=99dfcd6025165b1e4a275c0c8e322bf19709584a;p=netatalk.git change SIGHUP and SIGUSR1, SIGHUP reload config files, Volumes file are reloaded too if changed on get_srvparms. SIGUSR1 old SIGHUP semantic. --- diff --git a/etc/afpd/afp_dsi.c b/etc/afpd/afp_dsi.c index 8d135e52..1c1bc89b 100644 --- a/etc/afpd/afp_dsi.c +++ b/etc/afpd/afp_dsi.c @@ -1,5 +1,5 @@ /* - * $Id: afp_dsi.c,v 1.27 2003-03-12 15:07:00 didg Exp $ + * $Id: afp_dsi.c,v 1.27.2.1 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu) * Copyright (c) 1990,1993 Regents of The University of Michigan. @@ -71,7 +71,10 @@ static __inline__ void afp_dsi_close(AFPObj *obj) dsi_close(dsi); } -/* a little bit of code duplication. */ +/* ------------------------------- + * SIGTERM + * a little bit of code duplication. + */ static void afp_dsi_die(int sig) { dsi_attention(child.obj->handle, AFPATTN_SHUTDOWN); @@ -87,6 +90,9 @@ static void afp_dsi_die(int sig) } } +/* --------------------------------- + * SIGUSR1 down in five mn. +*/ static void afp_dsi_timedown() { struct sigaction sv; @@ -118,17 +124,29 @@ static void afp_dsi_timedown() afp_dsi_die(1); } - /* ignore SIGHUP */ + /* ignore myself */ sv.sa_handler = SIG_IGN; sigemptyset( &sv.sa_mask ); sv.sa_flags = SA_RESTART; - if ( sigaction( SIGHUP, &sv, 0 ) < 0 ) { + if ( sigaction( SIGUSR1, &sv, 0 ) < 0 ) { LOG(log_error, logtype_afpd, "afp_timedown: sigaction SIGHUP: %s", strerror(errno) ); afp_dsi_die(1); } } +/* --------------------------------- + * SIGHUP reload configuration file + * FIXME here or we wait ? +*/ +volatile reload_request = 0; + +static void afp_dsi_reload() +{ + reload_request = 1; +} + +/* ---------------------- */ #ifdef SERVERTEXT static void afp_dsi_getmesg (int sig) { @@ -137,6 +155,7 @@ static void afp_dsi_getmesg (int sig) } #endif /* SERVERTEXT */ +/* ---------------------- */ static void alarm_handler() { int err; @@ -155,8 +174,8 @@ int err; } -/* - * Signal handler for SIGUSR1 - set the debug flag and +/* --------------------------------- + * old signal handler for SIGUSR1 - set the debug flag and * redirect stdout to /afpd-debug-. */ void afp_set_debug (int sig) @@ -170,8 +189,9 @@ void afp_set_debug (int sig) return; } - -/* afp over dsi. this never returns. */ +/* ------------------------------------------- + afp over dsi. this never returns. +*/ void afp_over_dsi(AFPObj *obj) { DSI *dsi = (DSI *) obj->handle; @@ -186,22 +206,26 @@ void afp_over_dsi(AFPObj *obj) child.obj = obj; child.tickle = child.flags = 0; - /* install SIGTERM and SIGHUP */ memset(&action, 0, sizeof(action)); - action.sa_handler = afp_dsi_timedown; + + /* install SIGHUP */ + action.sa_handler = afp_dsi_reload; sigemptyset( &action.sa_mask ); sigaddset(&action.sa_mask, SIGALRM); sigaddset(&action.sa_mask, SIGTERM); + sigaddset(&action.sa_mask, SIGUSR1); action.sa_flags = SA_RESTART; if ( sigaction( SIGHUP, &action, 0 ) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); afp_dsi_die(1); } + /* install SIGTERM */ action.sa_handler = afp_dsi_die; sigemptyset( &action.sa_mask ); sigaddset(&action.sa_mask, SIGALRM); sigaddset(&action.sa_mask, SIGHUP); + sigaddset(&action.sa_mask, SIGUSR1); action.sa_flags = SA_RESTART; if ( sigaction( SIGTERM, &action, 0 ) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); @@ -220,10 +244,12 @@ void afp_over_dsi(AFPObj *obj) } #endif /* SERVERTEXT */ - /* SIGUSR1 - set "debug" flag on this process. */ - action.sa_handler = afp_set_debug; + /* SIGUSR1 - set down in 5 minutes */ + action.sa_handler = afp_dsi_timedown; sigemptyset( &action.sa_mask ); - sigaddset(&action.sa_mask, SIGUSR1); + sigaddset(&action.sa_mask, SIGALRM); + sigaddset(&action.sa_mask, SIGHUP); + sigaddset(&action.sa_mask, SIGTERM); action.sa_flags = SA_RESTART; if ( sigaction( SIGUSR1, &action, 0) < 0 ) { LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) ); @@ -245,6 +271,10 @@ void afp_over_dsi(AFPObj *obj) while ((cmd = dsi_receive(dsi))) { child.tickle = 0; dsi_sleep(dsi, 0); /* wake up */ + if (reload_request) { + reload_request = 0; + load_volumes(child.obj); + } if (cmd == DSIFUNC_TICKLE) { /* so we don't get killed on the client side. */ diff --git a/etc/afpd/afp_options.c b/etc/afpd/afp_options.c index 0dabeae2..ef6ddc14 100644 --- a/etc/afpd/afp_options.c +++ b/etc/afpd/afp_options.c @@ -1,5 +1,5 @@ /* - * $Id: afp_options.c,v 1.30 2003-04-16 22:45:08 samnoble Exp $ + * $Id: afp_options.c,v 1.30.2.1 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * Copyright (c) 1990,1993 Regents of The University of Michigan. @@ -100,10 +100,21 @@ static char *getoption(char *buf, const char *option) void afp_options_free(struct afp_options *opt, const struct afp_options *save) { - if (opt->defaultvol && (opt->defaultvol != save->defaultvol)) - free(opt->defaultvol); - if (opt->systemvol && (opt->systemvol != save->systemvol)) - free(opt->systemvol); + 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)) @@ -136,8 +147,8 @@ void afp_options_init(struct afp_options *options) memset(options, 0, sizeof(struct afp_options)); options->connections = 20; options->pidfile = _PATH_AFPDLOCK; - options->defaultvol = _PATH_AFPDDEFVOL; - options->systemvol = _PATH_AFPDSYSVOL; + options->defaultvol.name = _PATH_AFPDDEFVOL; + options->systemvol.name = _PATH_AFPDSYSVOL; options->configfile = _PATH_AFPDCONF; options->nlspath = _PATH_AFPDNLSPATH; options->uampath = _PATH_AFPDUAMPATH; @@ -227,9 +238,9 @@ int afp_options_parseline(char *buf, struct afp_options *options) /* figure out options w/ values. currently, this will ignore the setting * if memory is lacking. */ if ((c = getoption(buf, "-defaultvol")) && (opt = strdup(c))) - options->defaultvol = opt; + options->defaultvol.name = opt; if ((c = getoption(buf, "-systemvol")) && (opt = strdup(c))) - options->systemvol = opt; + options->systemvol.name = opt; if ((c = getoption(buf, "-loginmesg")) && (opt = strdup(c))) options->loginmesg = opt; if ((c = getoption(buf, "-guestname")) && (opt = strdup(c))) @@ -459,10 +470,10 @@ int afp_options_parse(int ac, char **av, struct afp_options *options) options->server = optarg; break; case 'f' : - options->defaultvol = optarg; + options->defaultvol.name = optarg; break; case 's' : - options->systemvol = optarg; + options->systemvol.name = optarg; break; case 'u' : options->flags |= OPTION_USERVOLFIRST; diff --git a/etc/afpd/enumerate.c b/etc/afpd/enumerate.c index 009cd051..4c8abb6c 100644 --- a/etc/afpd/enumerate.c +++ b/etc/afpd/enumerate.c @@ -1,5 +1,5 @@ /* - * $Id: enumerate.c,v 1.39.2.1 2003-05-20 14:49:19 didg Exp $ + * $Id: enumerate.c,v 1.39.2.2 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -354,7 +354,7 @@ int ext; sd.sd_sindex = 1; sd.sd_vid = vid; - sd.sd_did = did; + sd.sd_did = curdir->d_did; } /* diff --git a/etc/afpd/globals.h b/etc/afpd/globals.h index 7765c895..41b067e6 100644 --- a/etc/afpd/globals.h +++ b/etc/afpd/globals.h @@ -1,5 +1,5 @@ /* - * $Id: globals.h,v 1.18 2003-04-16 22:45:10 samnoble Exp $ + * $Id: globals.h,v 1.18.2.1 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -48,6 +48,13 @@ typedef struct uidgidset_t { /* a couple of these options could get stuck in unions to save * space. */ +struct afp_volume_name { + time_t mtime; + char *name; + char *full_name; + int loaded; +}; + struct afp_options { int connections, port, transports, tickleval, timeout, server_notif, flags; unsigned char passwdbits, passwdminlen, loginmaxfail; @@ -55,7 +62,9 @@ struct afp_options { char hostname[MAXHOSTNAMELEN + 1], *server, *ipaddr, *configfile; struct at_addr ddpaddr; char *uampath, *nlspath, *fqdn; - char *pidfile, *defaultvol, *systemvol; + char *pidfile; + struct afp_volume_name defaultvol, systemvol, uservol; + char *guest, *loginmesg, *keyfile, *passwdfile; char *uamlist; char *authprintdir; diff --git a/etc/afpd/main.c b/etc/afpd/main.c index 91ad85e9..02c3e148 100644 --- a/etc/afpd/main.c +++ b/etc/afpd/main.c @@ -1,5 +1,5 @@ /* - * $Id: main.c,v 1.20 2002-10-04 15:15:05 srittau Exp $ + * $Id: main.c,v 1.20.4.1 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -80,18 +80,21 @@ static void afp_exit(const int i) static void afp_goaway(int sig) { + #ifndef NO_DDP asp_kill(sig); #endif /* ! NO_DDP */ + dsi_kill(sig); switch( sig ) { case SIGTERM : LOG(log_info, logtype_afpd, "shutting down on signal %d", sig ); break; + case SIGUSR1 : case SIGHUP : /* w/ a configuration file, we can force a re-read if we want */ nologin++; - if ((nologin + 1) & 1) { + if (sig == SIGHUP || ((nologin + 1) & 1)) { AFPConfig *config; LOG(log_info, logtype_afpd, "re-reading configuration file"); @@ -114,6 +117,9 @@ static void afp_goaway(int sig) LOG(log_info, logtype_afpd, "disallowing logins"); auth_unload(); } + if (sig == SIGHUP) { + nologin = 0; + } break; default : LOG(log_error, logtype_afpd, "afp_goaway: bad signal" ); @@ -190,7 +196,12 @@ char **av; sigemptyset( &sv.sa_mask ); sigaddset(&sv.sa_mask, SIGHUP); sigaddset(&sv.sa_mask, SIGTERM); + sigaddset(&sv.sa_mask, SIGUSR1); sv.sa_flags = SA_RESTART; + if ( sigaction( SIGUSR1, &sv, 0 ) < 0 ) { + LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) ); + afp_exit(1); + } if ( sigaction( SIGHUP, &sv, 0 ) < 0 ) { LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) ); afp_exit(1); diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 72075c5d..cb71d1f5 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,5 +1,5 @@ /* - * $Id: volume.c,v 1.51.2.1 2003-05-26 11:04:36 didg Exp $ + * $Id: volume.c,v 1.51.2.2 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -77,13 +77,15 @@ extern int afprun(int root, char *cmd, int *outfd); #endif /* BYTE_ORDER == BIG_ENDIAN */ #endif /* ! NO_LARGE_VOL_SUPPORT */ -static struct vol *volumes = NULL; +static struct vol *Volumes = NULL; static int lastvid = 0; #ifndef CNID_DB static char *Trash = "\02\024Network Trash Folder"; #endif /* CNID_DB */ -static struct extmap *extmap = NULL, *defextmap = NULL; -static int extmap_cnt; + +static struct extmap *Extmap = NULL, *Defextmap = NULL; +static int Extmap_cnt; +static void free_extmap(void); #define VOLOPT_ALLOW 0 /* user allow list */ #define VOLOPT_DENY 1 /* user deny list */ @@ -470,6 +472,18 @@ static void volset(struct vol_option *options, struct vol_option *save, } } +/* ----------------- */ +static void showvol(const char *name) +{ + struct vol *volume; + for ( volume = Volumes; volume; volume = volume->v_next ) { + if ( !strcasecmp( volume->v_name, name ) && volume->v_hide) { + volume->v_hide = 0; + return; + } + } +} + /* ------------------------------- */ static int creatvol(AFPObj *obj, struct passwd *pwd, char *path, char *name, @@ -479,6 +493,7 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, { struct vol *volume; int vlen; + int hide = 0; if ( name == NULL || *name == '\0' ) { if ((name = strrchr( path, '/' )) == NULL) { @@ -490,9 +505,14 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, return -1; } - for ( volume = volumes; volume; volume = volume->v_next ) { + for ( volume = Volumes; volume; volume = volume->v_next ) { if ( strcasecmp( volume->v_name, name ) == 0 ) { - return -1; /* Won't be able to access it, anyway... */ + if (volume->v_deleted) { + hide = 1; + } + else { + return -1; /* Won't be able to access it, anyway... */ + } } } @@ -517,7 +537,7 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, free(volume); return -1; } - + volume->v_hide = hide; strcpy( volume->v_name, name); strcpy( volume->v_path, path ); @@ -583,8 +603,8 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, } } - volume->v_next = volumes; - volumes = volume; + volume->v_next = Volumes; + Volumes = volume; return 0; } @@ -660,26 +680,26 @@ int user; struct extmap *em; int cnt; - if (extmap == NULL) { - if (( extmap = calloc(1, sizeof( struct extmap ))) == NULL ) { + if (Extmap == NULL) { + if (( Extmap = calloc(1, sizeof( struct extmap ))) == NULL ) { LOG(log_error, logtype_afpd, "setextmap: calloc: %s", strerror(errno) ); return; } } ext++; - for ( em = extmap, cnt = 0; em->em_ext; em++, cnt++) { + for ( em = Extmap, cnt = 0; em->em_ext; em++, cnt++) { if ( (strdiacasecmp( em->em_ext, ext )) == 0 ) { break; } } if ( em->em_ext == NULL ) { - if (!(extmap = realloc( extmap, sizeof( struct extmap ) * (cnt +2))) ) { + if (!(Extmap = realloc( Extmap, sizeof( struct extmap ) * (cnt +2))) ) { LOG(log_error, logtype_afpd, "setextmap: realloc: %s", strerror(errno) ); return; } - (extmap +cnt +1)->em_ext = NULL; - em = extmap +cnt; + (Extmap +cnt +1)->em_ext = NULL; + em = Extmap +cnt; } else if ( !user ) { return; } @@ -715,22 +735,52 @@ static void sortextmap( void) { struct extmap *em; - extmap_cnt = 0; - if ((em = extmap) == NULL) { + Extmap_cnt = 0; + if ((em = Extmap) == NULL) { return; } while (em->em_ext) { em++; - extmap_cnt++; + Extmap_cnt++; } - if (extmap_cnt) { - qsort(extmap, extmap_cnt, sizeof(struct extmap), extmap_cmp); - defextmap = extmap; + if (Extmap_cnt) { + qsort(Extmap, Extmap_cnt, sizeof(struct extmap), extmap_cmp); + Defextmap = Extmap; } } +/* ---------------------- +*/ +static void free_extmap( void) +{ + if (Extmap) { + free(Extmap); + Extmap = NULL; + Defextmap = Extmap; + Extmap_cnt = 0; + } +} -/* +/* ---------------------- +*/ +static int volfile_changed(struct afp_volume_name *p) +{ + struct stat st; + char *name; + + if (p->full_name) + name = p->full_name; + else + name = p->name; + + if (!stat( name, &st) && st.st_mtime > p->mtime) { + p->mtime = st.st_mtime; + return 1; + } + return 0; +} + +/* ---------------------- * Read a volume configuration file and add the volumes contained within to * the global volume list. If p2 is non-NULL, the file that is opened is * p1/p2 @@ -743,7 +793,8 @@ static void sortextmap( void) */ static int readvolfile(obj, p1, p2, user, pwent) AFPObj *obj; -char *p1, *p2; +struct afp_volume_name *p1; +char *p2; int user; struct passwd *pwent; { @@ -755,19 +806,29 @@ struct passwd *pwent; struct passwd *pw; struct vol_option options[VOLOPT_NUM], save_options[VOLOPT_NUM]; int i; + struct stat st; + int fd; - if (!p1) + if (!p1->name) return -1; - - strcpy( path, p1 ); + p1->mtime = 0; + strcpy( path, p1->name ); if ( p2 != NULL ) { strcat( path, "/" ); strcat( path, p2 ); + if (p1->full_name) { + free(p1->full_name); + } + p1->full_name = strdup(path); } if (NULL == ( fp = fopen( path, "r" )) ) { return( -1 ); } + fd = fileno(fp); + if (fd != -1 && !fstat( fd, &st) ) { + p1->mtime = st.st_mtime; + } memset(save_options, 0, sizeof(save_options)); while ( myfgets( buf, sizeof( buf ), fp ) != NULL ) { @@ -892,40 +953,91 @@ struct passwd *pwent; if ( fclose( fp ) != 0 ) { LOG(log_error, logtype_afpd, "readvolfile: fclose: %s", strerror(errno) ); } + p1->loaded = 1; return( 0 ); } +/* ------------------------------- */ +static void volume_free(struct vol *vol) +{ + free(vol->v_name); + vol->v_name = NULL; + free(vol->v_path); + codepage_free(vol); + free(vol->v_password); + free(vol->v_veto); +#ifdef CNID_DB + free(vol->v_dbpath); +#endif /* CNID_DB */ +#ifdef FORCE_UIDGID + free(vol->v_forceuid); + free(vol->v_forcegid); +#endif /* FORCE_UIDGID */ +} -static void load_volumes(AFPObj *obj) +/* ------------------------------- */ +static void free_volumes(void ) { - struct passwd *pwent = getpwnam(obj->username); + struct vol *vol; + struct vol *nvol, *ovol; - if ( (obj->options.flags & OPTION_USERVOLFIRST) == 0 ) { - readvolfile(obj, obj->options.systemvol, NULL, 0, pwent); + for ( vol = Volumes; vol; vol = vol->v_next ) { + if (( vol->v_flags & AFPVOL_OPEN ) ) { + vol->v_deleted = 1; + continue; + } + volume_free(vol); + } + + for ( vol = Volumes, ovol = NULL; vol; vol = nvol) { + nvol = vol->v_next; + + if (vol->v_name == NULL) { + if (Volumes == vol) { + Volumes = nvol; + } + if (!ovol) { + ovol = Volumes; + } + else { + ovol->v_next = nvol; + } + free(vol); + } + else { + ovol = vol; + } } +} - if ((*obj->username == '\0') || (obj->options.flags & OPTION_NOUSERVOL)) { - readvolfile(obj, obj->options.defaultvol, NULL, 1, pwent); - } else if (pwent) { - /* - * Read user's AppleVolumes or .AppleVolumes file - * If neither are readable, read the default volumes file. if - * that doesn't work, create a user share. - */ - if ( readvolfile(obj, pwent->pw_dir, "AppleVolumes", 1, pwent) < 0 && - readvolfile(obj, pwent->pw_dir, ".AppleVolumes", 1, pwent) < 0 && - readvolfile(obj, pwent->pw_dir, "applevolumes", 1, pwent) < 0 && - readvolfile(obj, pwent->pw_dir, ".applevolumes", 1, pwent) < 0 && - obj->options.defaultvol != NULL ) { - if (readvolfile(obj, obj->options.defaultvol, NULL, 1, pwent) < 0) - creatvol(obj, pwent, pwent->pw_dir, NULL, NULL, 1); - } +/* ------------------------------- */ +static void volume_unlink(struct vol *volume) +{ +struct vol *vol, *ovol, *nvol; + + if (volume == Volumes) { + Volumes = Volumes->v_next; + return; } - if ( obj->options.flags & OPTION_USERVOLFIRST ) { - readvolfile(obj, obj->options.systemvol, NULL, 0, pwent ); + for ( vol = Volumes, ovol = NULL; vol; vol = nvol) { + nvol = vol->v_next; + + if (vol == volume) { + if (!ovol) { + ovol = Volumes; + } + else { + ovol->v_next = nvol; + } + break; + } + else { + ovol = vol; + } } } + static int getvolspace( vol, bfree, btotal, xbfree, xbtotal, bsize ) struct vol *vol; u_int32_t *bfree, *btotal, *bsize; @@ -1165,7 +1277,60 @@ int *buflen; return( AFP_OK ); } -/* ------------------------- */ +/* ------------------------------- */ +void load_volumes(AFPObj *obj) +{ + struct passwd *pwent; + + if (Volumes) { + int changed = 0; + + /* check files date */ + if (obj->options.defaultvol.loaded) { + changed = volfile_changed(&obj->options.defaultvol); + } + if (obj->options.systemvol.loaded) { + changed |= volfile_changed(&obj->options.systemvol); + } + if (obj->options.uservol.loaded) { + changed |= volfile_changed(&obj->options.uservol); + } + if (!changed) + return; + + free_extmap(); + free_volumes(); + } + + pwent = getpwnam(obj->username); + if ( (obj->options.flags & OPTION_USERVOLFIRST) == 0 ) { + readvolfile(obj, &obj->options.systemvol, NULL, 0, pwent); + } + + if ((*obj->username == '\0') || (obj->options.flags & OPTION_NOUSERVOL)) { + readvolfile(obj, &obj->options.defaultvol, NULL, 1, pwent); + } else if (pwent) { + /* + * Read user's AppleVolumes or .AppleVolumes file + * If neither are readable, read the default volumes file. if + * that doesn't work, create a user share. + */ + obj->options.uservol.name = strdup(pwent->pw_dir); + if ( readvolfile(obj, &obj->options.uservol, "AppleVolumes", 1, pwent) < 0 && + readvolfile(obj, &obj->options.uservol, ".AppleVolumes", 1, pwent) < 0 && + readvolfile(obj, &obj->options.uservol, "applevolumes", 1, pwent) < 0 && + readvolfile(obj, &obj->options.uservol, ".applevolumes", 1, pwent) < 0 && + obj->options.defaultvol.name != NULL ) { + if (readvolfile(obj, &obj->options.defaultvol, NULL, 1, pwent) < 0) + creatvol(pwent->pw_dir, NULL, NULL); + } + } + if ( obj->options.flags & OPTION_USERVOLFIRST ) { + readvolfile(obj, &obj->options.systemvol, NULL, 0, pwent ); + } +} + +/* ------------------------------- */ int afp_getsrvrparms(obj, ibuf, ibuflen, rbuf, rbuflen ) AFPObj *obj; char *ibuf, *rbuf; @@ -1178,11 +1343,10 @@ int ibuflen, *rbuflen; int vcnt, len; - if (!volumes) - load_volumes(obj); + load_volumes(obj); data = rbuf + 5; - for ( vcnt = 0, volume = volumes; volume; volume = volume->v_next ) { + for ( vcnt = 0, volume = Volumes; volume; volume = volume->v_next ) { if ( stat( volume->v_path, &st ) < 0 ) { LOG(log_info, logtype_afpd, "afp_getsrvrparms: stat %s: %s", volume->v_path, strerror(errno) ); @@ -1191,7 +1355,10 @@ int ibuflen, *rbuflen; if (!S_ISDIR(st.st_mode)) { continue; /* not a dir */ } - + if (volume->v_hide) { + continue; /* config file changed but the volume was mounted */ + + } /* set password bit if there's a volume password */ *data = (volume->v_password) ? AFPSRVR_PASSWD : 0; @@ -1260,10 +1427,9 @@ int ibuflen, *rbuflen; if ((len + 1) & 1) /* pad to an even boundary */ ibuf++; - if (!volumes) - load_volumes(obj); + load_volumes(obj); - for ( volume = volumes; volume; volume = volume->v_next ) { + for ( volume = Volumes; volume; volume = volume->v_next ) { if ( strcasecmp( volname, volume->v_name ) == 0 ) { break; } @@ -1470,7 +1636,7 @@ int ibuflen, *rbuflen; } vol->v_flags &= ~AFPVOL_OPEN; - for ( ovol = volumes; ovol; ovol = ovol->v_next ) { + for ( ovol = Volumes; ovol; ovol = ovol->v_next ) { if ( ovol->v_flags & AFPVOL_OPEN ) { break; } @@ -1481,7 +1647,29 @@ int ibuflen, *rbuflen; curdir = ovol->v_dir; } } - closevol(vol); + dirfree( vol->v_root ); + vol->v_dir = NULL; +#ifdef CNID_DB + cnid_close(vol->v_db); + vol->v_db = NULL; +#endif /* CNID_DB */ + +#ifdef AFP3x + if (vol->v_utf8toucs2 != (iconv_t)(-1)) + iconv_close(vol->v_utf8toucs2); + if (vol->v_ucs2toutf8 != (iconv_t)(-1)) + iconv_close(vol->v_ucs2toutf8); + if (vol->v_mactoutf8 != (iconv_t)(-1)) + iconv_close(vol->v_mactoutf8); + if (vol->v_ucs2tomac != (iconv_t)(-1)) + iconv_close(vol->v_ucs2tomac); +#endif + + if (vol->v_deleted) { + showvol(vol->v_name); + volume_free(vol); + volume_unlink(vol); + } return( AFP_OK ); } @@ -1490,7 +1678,7 @@ struct vol *getvolbyvid(const u_int16_t vid ) { struct vol *vol; - for ( vol = volumes; vol; vol = vol->v_next ) { + for ( vol = Volumes; vol; vol = vol->v_next ) { if ( vid == vol->v_vid ) { break; } @@ -1519,24 +1707,24 @@ struct extmap *getextmap(const char *path) struct extmap *em; if (NULL == ( p = strrchr( path, '.' )) ) { - return( defextmap ); + return( Defextmap ); } p++; - if (!*p || !extmap_cnt) { - return( defextmap ); + if (!*p || !Extmap_cnt) { + return( Defextmap ); } - em = bsearch(p, extmap, extmap_cnt, sizeof(struct extmap), ext_cmp_key); + em = bsearch(p, Extmap, Extmap_cnt, sizeof(struct extmap), ext_cmp_key); if (em) { return( em ); } else { - return( defextmap ); + return( Defextmap ); } } /* ------------------------- */ struct extmap *getdefextmap(void) { - return( defextmap ); + return( Defextmap ); } /* -------------------------- @@ -1555,7 +1743,7 @@ AFPObj *obj; if ( gettimeofday( &tv, 0 ) < 0 ) return 0; - for ( vol = volumes; vol; vol = vol->v_next ) { + for ( vol = Volumes; vol; vol = vol->v_next ) { if ( (vol->v_flags & AFPVOL_OPEN) && vol->v_time + 30 < tv.tv_sec) { if ( !stat( vol->v_path, &st ) && vol->v_time != st.st_mtime ) { vol->v_time = st.st_mtime; diff --git a/etc/afpd/volume.h b/etc/afpd/volume.h index e5e9d219..f6a0a034 100644 --- a/etc/afpd/volume.h +++ b/etc/afpd/volume.h @@ -1,5 +1,5 @@ /* - * $Id: volume.h,v 1.19.2.1 2003-05-26 11:04:36 didg Exp $ + * $Id: volume.h,v 1.19.2.2 2003-05-26 11:17:25 didg Exp $ * * Copyright (c) 1990,1994 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -77,6 +77,8 @@ struct vol { iconv_t *v_mactoutf8; iconv_t *v_ucs2tomac; #endif + int v_deleted; /* volume open but deleted in new config file */ + int v_hide; /* new volume wait open volume */ char *v_root_preexec; char *v_preexec; @@ -184,10 +186,13 @@ extern int ustatfs_getvolspace __P((const struct vol *, u_int32_t *)); extern int codepage_init __P((struct vol *, const int, const int)); +extern void codepage_free __P((struct vol *vol)); + extern int codepage_read __P((struct vol *, const char *)); extern union codepage_val codepage_find __P(()); extern void setvoltime __P((AFPObj *, struct vol *)); extern int pollvoltime __P((AFPObj *)); +extern void load_volumes __P((AFPObj *obj)); /* FP functions */ extern int afp_openvol __P((AFPObj *, char *, int, char *, int *));