/*
- * $Id: afp_dsi.c,v 1.27.2.3.2.4 2004-05-04 15:38:24 didg Exp $
+ * $Id: afp_dsi.c,v 1.27.2.3.2.4.2.1 2005-03-31 00:25:55 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
* Copyright (c) 1990,1993 Regents of The University of Michigan.
*/
static void afp_dsi_die(int sig)
{
+static volatile int in_handler;
+
+ if (in_handler) {
+ return;
+ }
+ /* it's not atomic but we don't care because it's an exit function
+ * ie if a signal is received here, between the test and the affectation,
+ * it will not return.
+ */
+ in_handler = 1;
+
dsi_attention(child.obj->handle, AFPATTN_SHUTDOWN);
afp_dsi_close(child.obj);
if (sig) /* if no signal, assume dieing because logins are disabled &
/*
- * $Id: server_child.c,v 1.7.4.1.2.4 2004-07-01 01:27:34 didg Exp $
+ * $Id: server_child.c,v 1.7.4.1.2.4.2.1 2005-03-31 00:25:55 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
#define HASH(i) ((((i) >> 8) ^ (i)) & (CHILD_HASHSIZE - 1))
struct server_child_data {
- pid_t pid;
- uid_t uid;
- int valid;
- u_int32_t time;
- u_int32_t idlen;
-
- char *clientid;
+ pid_t pid; /* afpd worker process pid (from the worker afpd process )*/
+ uid_t uid; /* user id of connected client (from the worker afpd process) */
+ int valid; /* 1 if we have a clientid */
+ u_int32_t time; /* client boot time (from the mac client) */
+ int killed; /* 1 if we already tried to kill the client */
+
+ u_int32_t idlen; /* clientid len (from the Mac client) */
+ char *clientid; /* clientid (from the Mac client) */
struct server_child_data **prevp, *next;
};
child->pid = pid;
child->valid = 0;
+ child->killed = 0;
hash_child(fork->table, child);
children->count++;
sigprocmask(SIG_SETMASK, &oldsig, NULL);
* a plain-old linked list
* FIXME use resolve_child ?
*/
+static int kill_child(struct server_child_data *child)
+{
+ if (!child->killed) {
+ kill(child->pid, SIGTERM);
+ /* we don't wait because there's no guarantee that we can really kill it */
+ child->killed = 1;
+ return 1;
+ }
+ else {
+ LOG(log_info, logtype_default, "Already tried to kill (%d) before! Still there?", child->pid);
+ }
+ return 0;
+}
+
+/* -------------------- */
void server_child_kill_one(server_child *children, const int forkid, const pid_t pid, const uid_t uid)
{
server_child_fork *fork;
LOG(log_info, logtype_default, "Disconnecting old session (%d) not the same user, bailout!", child->pid);
}
else {
- kill(child->pid, SIGTERM);
+ kill_child(child);
}
}
child = tmp;
if ( child->idlen == idlen && !memcmp(child->clientid, id, idlen)) {
if ( child->time != boottime ) {
if (uid == child->uid) {
- kill(child->pid, SIGTERM);
- LOG(log_info, logtype_default, "Disconnecting old session %d, client rebooted.", child->pid);
+ if (kill_child(child)) {
+ LOG(log_info, logtype_default, "Disconnecting old session %d, client rebooted.", child->pid);
+ }
}
else {
LOG(log_info, logtype_default, "Disconnecting old session not the same uid, bailout!");
}
}
+ else if (child->killed) {
+ /* there's case where a Mac close a connection and restart a new one before
+ * the first is 'waited' by the master afpd process
+ */
+ LOG(log_info, logtype_default,
+ "WARNING: connection (%d) killed but still there.", child->pid);
+ }
else {
LOG(log_info, logtype_default,
"WARNING: 2 connections (%d, %d), boottime identical, don't know if one needs to be disconnected.",