]> arthur.barton.de Git - netatalk.git/commitdiff
change SIGHUP and SIGUSR1, SIGHUP reload config files, Volumes file are reloaded...
authordidg <didg>
Mon, 26 May 2003 11:17:25 +0000 (11:17 +0000)
committerdidg <didg>
Mon, 26 May 2003 11:17:25 +0000 (11:17 +0000)
etc/afpd/afp_dsi.c
etc/afpd/afp_options.c
etc/afpd/enumerate.c
etc/afpd/globals.h
etc/afpd/main.c
etc/afpd/volume.c
etc/afpd/volume.h

index 8d135e528430d5749fb5feb0b85305d1fcc722ff..1c1bc89bca80df4f2f3eb33aa7c13d9f9002ae69 100644 (file)
@@ -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 <tmpdir>/afpd-debug-<pid>.
  */
 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. */
index 0dabeae22dd4c7dfb2a42340cd870a233c801f1e..ef6ddc144e2e12c4102b672e2ecce06cad5dee4c 100644 (file)
@@ -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;
index 009cd051b360dc191ffd9d91eeca0b171c6dee48..4c8abb6c85e4819fdf389862503dfdd97e01cbcb 100644 (file)
@@ -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;
     }
 
     /*
index 7765c895d74ace138b944b10c1167161e7fb52c3..41b067e6abae0f36195deb3aec2db16651b057f8 100644 (file)
@@ -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;
index 91ad85e9909afa52a0d31b2f8b7114fb1a1151a0..02c3e14847650a2da18434b28be1c520e835dc7b 100644 (file)
@@ -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);
index 72075c5df462f2655636e3989ddca0de837a953a..cb71d1f58e641224bb760e074afab2ff48a0d991 100644 (file)
@@ -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;
index e5e9d2197f29e30353ddb8bca9b3f479f16f5f50..f6a0a03480d255439996a09c4d9eff2f79d2d794 100644 (file)
@@ -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 *));