-/*
- * $Source$
- * $Header$
+/* $Id$
+ *
+ * Copyright 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*/
-/* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
-/* For copying and distribution information, please see the file */
-/* <mit-copyright.h>. */
-
-#ifndef lint
-static char *rcsid_dispatch_c = "$Header$";
-#endif
#include <mit-copyright.h>
+#include <moira.h>
+#include "update_server.h"
+
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
-#include <gdb.h>
-#include <errno.h>
#include <string.h>
-#include <pwd.h>
-#include <moira.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#ifdef POSIX
-#include <termios.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#ifdef HAVE_KRB4
+#include <des.h>
#endif
#include "update.h"
-#include "des.h"
-
-extern int auth_002(), xfer_002(), xfer_003(), exec_002();
-extern int sync_proc(), quit();
-extern char *config_lookup();
+RCSID("$Header$");
-extern void gdb_debug();
-extern int errno;
-
-CONNECTION conn;
-int code, log_priority;
-char *whoami;
+char *whoami, *hostname;
int have_authorization = 0;
-C_Block session;
-int have_file = 0;
-int done = 0;
+#ifdef HAVE_KRB4
+des_cblock session;
+#endif
int uid = 0;
-#define send_int(n) \
- (_send_int = (n), send_object(conn, (char *)&_send_int, INTEGER_T))
-int _send_int;
+void child_handler(int signal);
+static void syslog_com_err_proc(const char *progname, long code,
+ const char *fmt, va_list args);
struct _dt {
char *str;
- int (*proc)();
+ void (*proc)(int, char *);
} dispatch_table[] = {
{ "AUTH_002", auth_002 },
+ { "AUTH_003", auth_003 },
{ "XFER_002", xfer_002 },
{ "XFER_003", xfer_003 },
{ "EXEC_002", exec_002 },
{ "quit", quit },
- { NULL, (int (*)())abort }
+ { NULL, (void (*)(int, char *))abort }
};
-/* general scratch space -- useful for building error messages et al... */
-char buf[BUFSIZ];
-
int main(int argc, char **argv)
{
- STRING str;
+ char *str, *p;
+ size_t len;
struct _dt *d;
- char *p;
- int n;
+ struct utsname name;
+ int s, conn;
+ struct sigaction sa;
whoami = strrchr(argv[0], '/');
if (whoami)
exit(0);
setsid();
}
- else
- gdb_debug(GDB_NOFORK);
+
+ uname(&name);
+ hostname = name.nodename;
umask(0022);
- initialize_sms_error_table();
- initialize_krb_error_table();
- mr_update_initialize();
+ mr_init();
- /* wait for connection */
- gdb_init();
- /* If the config file contains a line "port portname", the daemon
- * will listen on the named port rather than SERVICE_NAME "sms_update"
- */
- if (!(p = config_lookup("port")))
- p = SERVICE_NAME;
- conn = create_forking_server(p, 0);
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = child_handler;
+ sigaction(SIGCHLD, &sa, NULL);
/* If the config file contains a line "user username", the
* daemon will run with that user's UID.
uid = pw->pw_uid;
}
+ /* If the config file contains a line "port portname", the daemon
+ * will listen on the named port rather than SERVICE_NAME ("moira_update")
+ */
+ if (!(p = config_lookup("port")))
+ p = SERVICE_NAME;
+
+ s = mr_listen(p);
+ if (s == -1)
+ {
+ com_err(whoami, errno, "creating listening socket");
+ exit(1);
+ }
+
+ set_com_err_hook(syslog_com_err_proc);
+ openlog(whoami, LOG_PID, LOG_DAEMON);
+
+ /* now loop waiting for connections */
+ while (1)
+ {
+ struct sockaddr_in client;
+ long len;
+ char *buf;
+
+ conn = mr_accept(s, &client);
+ if (conn == -1)
+ {
+ com_err(whoami, errno, "accepting on listening socket");
+ exit(1);
+ }
+ else if (conn == 0)
+ continue;
+
+ if (config_lookup("nofork") || (fork() <= 0))
+ break;
+
+ close(conn);
+ }
+
/* If the config file contains a line "chroot /dir/name", the
* daemon will run chrooted to that directory.
*/
}
}
- if (!conn)
- {
- com_err(whoami, errno, "can't get connection");
- exit(1);
- }
- if (connection_status(conn) == CON_STOPPED)
- {
- com_err(whoami, connection_errno(conn), ": can't get connection");
- exit(1);
- }
+ com_err(whoami, 0, "got connection");
- mr_log_info("got connection");
- /* got a connection; loop forever */
while (1)
{
- register char *cp;
- code = receive_object(conn, (char *)&str, STRING_T);
+ char *cp, *str;
+ size_t len;
+ int code;
+
+ code = recv_string(conn, &str, &len);
if (code)
{
- com_err(whoami, connection_errno(conn), "receiving command");
- sever_connection(conn);
+ com_err(whoami, code, "receiving command");
+ close(conn);
exit(1);
}
- cp = strchr(STRING_DATA(str), ' ');
+
+ cp = strchr(str, ' ');
if (cp)
*cp = '\0';
for (d = dispatch_table; d->str; d++)
{
- if (!strcmp(d->str, STRING_DATA(str)))
+ if (!strcmp(d->str, str))
{
if (cp)
*cp = ' ';
- (d->proc)(STRING_DATA(str));
+ (d->proc)(conn, str);
goto ok;
}
}
- sprintf(buf, "unknown request received: %s\n", STRING_DATA(str));
- mr_log_error(buf);
- code = send_int(MR_UNKNOWN_PROC);
+ com_err(whoami, 0, "unknown request received: %s", str);
+ code = send_int(conn, MR_UNKNOWN_PROC);
if (code)
- com_err(whoami, connection_errno(conn), "sending UNKNOWN_PROC");
+ com_err(whoami, code, "sending UNKNOWN_PROC");
ok:
- string_free(&str);
+ free(str);
}
}
-int send_ok(void)
+int send_ok(int conn)
{
- static int zero = 0;
- return code = send_object(conn, (char *)&zero, INTEGER_T);
+ return send_int(conn, 0);
}
-
-initialize(void)
-{
- /* keep have_authorization around */
- have_file = 0;
- done = 0;
-}
-
-
/*
* quit request:
*
* function:
* closes connection from MR
*/
-int quit(char *str)
+
+void quit(int conn, char *str)
{
- send_ok();
- sever_connection(conn);
- mr_log_info("Closing connection.");
+ send_ok(conn);
+ close(conn);
+ com_err(whoami, 0, "Closing connection.");
exit(0);
}
-
-/*
- * lose(msg)
- *
- * put <msg> to log as error, break connection, and exit
- */
-
-lose(char *msg)
+void fail(int conn, int err, char *msg)
{
- com_err(whoami, code, msg);
- if (conn)
- sever_connection(conn);
+ com_err(whoami, err, msg);
+ close(conn);
exit(1);
}
-/*
- * report_error(msg)
- *
- * send back (external) <code>; if error, punt big with <lose(msg)>
- */
-
-report_error(char *msg)
+void child_handler(int signal)
{
- code = send_object(conn, (char *)&code, INTEGER_T);
- if (code)
- {
- code = connection_errno(conn);
- lose(msg);
- }
-}
+ int status;
-/*
- * reject_call(c)
- *
- * set (external) <code> to <c> and call <report_error>
- */
+ while (waitpid(-1, &status, WNOHANG) > 0)
+ ;
+}
-reject_call(int c)
+static void syslog_com_err_proc(const char *progname, long code,
+ const char *fmt, va_list args)
{
- code = c;
- report_error("call rejected");
+ char buf[BUFSIZ + 1];
+
+ buf[BUFSIZ] = '\0';
+
+ vsnprintf(buf, BUFSIZ, fmt, args);
+ syslog(LOG_NOTICE, "%s: %s %s", progname ? progname : "",
+ code ? error_message(code) : "", buf);
}