#include <string.h>
#include <unistd.h>
+#ifdef HAVE_KRB4
#include <krb.h>
+#endif
+#include <krb5.h>
RCSID("$Header$");
-extern char *krb_get_lrealm(char *, int);
-
client *cur_client;
char *whoami;
time_t now;
char *host;
-char krb_realm[REALM_SZ];
+krb5_context context = NULL;
+char *krb_realm = NULL;
/* Client array and associated data. This needs to be global for _list_users */
client **clients;
int nclients, clientssize;
int dormant;
+int child_exited_abnormally = 0;
+int child_pid, child_signal, child_status;
void reapchild(int x);
void godormant(int x);
}
}
- krb_get_lrealm(krb_realm, 1);
+ status = krb5_init_context(&context);
+ if (status)
+ {
+ com_err(whoami, status, "Initializing krb5 context.");
+ exit(1);
+ }
+
+ status = krb5_get_default_realm(context, &krb_realm);
+ if (status)
+ {
+ com_err(whoami, status, "Getting default Kerberos realm.");
+ exit(1);
+ }
/*
* Database initialization. Only init if database should be open.
com_err(whoami, errno, "Unable to get local hostname");
exit(1);
}
- host = canonicalize_hostname(strdup(uts.nodename));
+ host = canonicalize_hostname(xstrdup(uts.nodename));
for (p = host; *p && *p != '.'; p++)
{
if (isupper(*p))
*/
nclients = 0;
clientssize = 10;
- clients = malloc(clientssize * sizeof(client *));
+ clients = xmalloc(clientssize * sizeof(client *));
mr_setup_signals();
/*
* Establish template connection.
*/
- if (!(listener = mr_listen(port)))
+ listener = mr_listen(port);
+ if (listener == -1)
{
- com_err(whoami, status, "trying to create listening connection");
+ com_err(whoami, MR_ABORTED, "trying to create listening connection");
exit(1);
}
FD_ZERO(&xreadfds);
while (!takedown)
{
int i;
- struct timeval timeout;
+ struct timeval timeout = {60, 0}; /* 1 minute */
/* If we're supposed to go down and we can, do it */
- if ((dormant == AWAKE) && (nclients == 0) &&
- (stat(MOIRA_MOTD_FILE, &stbuf) == 0))
+ if (((dormant == AWAKE) && (nclients == 0) &&
+ (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) ||
+ (dormant == SLEEPY))
{
mr_close_database();
com_err(whoami, 0, "database closed");
/* Block until something happens. */
memcpy(&readfds, &xreadfds, sizeof(readfds));
memcpy(&writefds, &xwritefds, sizeof(writefds));
- /* XXX set timeout */
- if (select(nfds, &readfds, &writefds, NULL, NULL) == -1)
+ if (select(nfds, &readfds, &writefds, NULL, &timeout) == -1)
{
if (errno != EINTR)
com_err(whoami, errno, "in select");
if (takedown)
break;
+
+ if (child_exited_abnormally)
+ {
+ critical_alert("moirad", "%d: child exits with signal %d status %d",
+ child_pid, child_signal, child_status);
+ child_exited_abnormally = 0;
+ }
+
time(&now);
if (!inc_running || now - inc_started > INC_TIMEOUT)
next_incremental();
/* Handle any new connections */
if (FD_ISSET(listener, &readfds))
{
- int newconn;
+ int newconn, addrlen = sizeof(struct sockaddr_in);
struct sockaddr_in addr;
client *cp;
- newconn = mr_accept(listener, &addr);
+ newconn = accept(listener, (struct sockaddr *)&addr, &addrlen);
if (newconn == -1)
com_err(whoami, errno, "accepting new connection");
else if (newconn > 0)
cp->tuplessize = 1;
cp->tuples = xmalloc(sizeof(mr_params));
memset(cp->tuples, 0, sizeof(mr_params));
+ cp->state = CL_ACCEPTING;
+ cp->version = 2;
cur_client = cp;
com_err(whoami, 0,
if (!clients[i]->ntuples)
{
FD_CLR(clients[i]->con, &xwritefds);
- /* Now that we're done writing we can read again */
FD_SET(clients[i]->con, &xreadfds);
}
clients[i]->last_time_used = now;
if (FD_ISSET(clients[i]->con, &readfds))
{
- client_read(clients[i]);
- if (clients[i]->ntuples)
- FD_SET(clients[i]->con, &xwritefds);
- clients[i]->last_time_used = now;
+ if (clients[i]->state == CL_ACCEPTING)
+ {
+ switch(mr_cont_accept(clients[i]->con,
+ &clients[i]->hsbuf,
+ &clients[i]->hslen))
+ {
+ case -1:
+ break;
+
+ case 0:
+ clients[i]->state = CL_CLOSING;
+ break;
+
+ default:
+ clients[i]->state = CL_ACTIVE;
+ clients[i]->hsbuf = NULL;
+ break;
+ }
+ }
+ else
+ {
+ client_read(clients[i]);
+ if (clients[i]->ntuples)
+ {
+ FD_CLR(clients[i]->con, &xreadfds);
+ FD_SET(clients[i]->con, &xwritefds);
+ }
+ clients[i]->last_time_used = now;
+ }
}
if (clients[i]->last_time_used < tardy)
{
com_err(whoami, 0, "Shutting down connection due to inactivity");
- clients[i]->done = 1;
+ clients[i]->state = CL_CLOSING;
}
- if (clients[i]->done)
+ if (clients[i]->state == CL_CLOSING)
{
client *old;
close(clients[i]->con);
FD_CLR(clients[i]->con, &xreadfds);
FD_CLR(clients[i]->con, &xwritefds);
- for (; clients[i]->ntuples; clients[i]->ntuples--)
- mr_destroy_reply(clients[i]->tuples[clients[i]->ntuples - 1]);
+ free_rtn_tuples(clients[i]);
free(clients[i]->tuples);
+ free(clients[i]->hsbuf);
old = clients[i];
clients[i] = clients[--nclients];
free(old);
if (pid == inc_pid)
inc_running = 0;
if (!takedown && (WTERMSIG(status) != 0 || WEXITSTATUS(status) != 0))
- com_err(whoami, 0, "%d: child exits with signal %d status %d",
- pid, WTERMSIG(status), WEXITSTATUS(status));
+ {
+ child_exited_abnormally = 1;
+ child_pid = pid;
+ child_signal = WTERMSIG(status);
+ child_status = WEXITSTATUS(status);
+ }
}
}
exit(1);
}
+ action.sa_handler = SIG_IGN;
+ if (sigaction(SIGPIPE, &action, NULL) < 0)
+ {
+ com_err(whoami, errno, "Unable to establish signal handlers.");
+ exit(1);
+ }
+
action.sa_handler = reapchild;
sigaddset(&action.sa_mask, SIGCHLD);
if (sigaction(SIGCHLD, &action, NULL) < 0)