]> andersk Git - moira.git/blobdiff - update/update_server.c
- Don't ifdef out auth_002; it breaks backward compatability.
[moira.git] / update / update_server.c
index 0615463733456cd1dec91c26b65e8d3707db3f96..63be9f773dfc74e568c4a78017a875cd25e43265 100644 (file)
-/*
- *     $Source$
- *     $Header$
+/* $Id$
+ *
+ * Copyright 1988-1998 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 lint
+#include <mit-copyright.h>
+#include <moira.h>
+#include "update_server.h"
 
-#include <stdio.h>
-#include "gdb.h"
-#include <errno.h>
-#include <strings.h>
-#include "update.h"
-#include "sms_update_int.h"
-#include "smsu_int.h"
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
 
-/* XXX */
-#include "kludge.h"
-/* XXX */
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
-extern int auth_001(), exec_001(), inst_001(), xfer_001();
-extern int xfer_002(), exec_002();
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+
+#ifdef HAVE_KRB4
+#include <des.h>
+#endif
+#include "update.h"
 
-extern int sync_proc(), quit();
+RCSID("$Header$");
 
-extern void gdb_debug();
-extern int exit(), abort(), errno;
+char *whoami, *hostname;
 
-CONNECTION conn;
-int code;
-char *whoami;
+int have_authorization = 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)();
+  char *str;
+  void (*proc)(int, char *);
 } dispatch_table[] = {
-     { "INST_001", inst_001 },
-     { "AUTH_001", auth_001 },
-     { "XFER_001", xfer_001 },
-     { "EXEC_001", exec_001 },
-     { "XFER_002", xfer_002 },
-     { "EXEC_002", exec_002 },
-     { "quit", quit },
-     { (char *)NULL, abort }
+  { "AUTH_002", auth_002 },
+  { "AUTH_003", auth_003 },
+  { "XFER_002", xfer_002 },
+  { "XFER_003", xfer_003 },
+  { "EXEC_002", exec_002 },
+  { "quit", quit },
+  { NULL, (void (*)(int, char *))abort }
 };
 
+int main(int argc, char **argv)
+{
+  char *str, *p;
+  size_t len;
+  struct _dt *d;
+  struct utsname name;
+  int s, conn;
+  struct sigaction sa;
+
+  whoami = strrchr(argv[0], '/');
+  if (whoami)
+    whoami++;
+  else
+    whoami = argv[0];
+
+  /* interpret arguments here */
+  if (argc != 1)
+    {
+      fprintf(stderr, "Usage:  %s\n", whoami);
+      exit(1);
+    }
+
+  if (!config_lookup("nofork"))
+    {
+      if (fork())
+       exit(0);
+      setsid();
+    }
+
+  uname(&name);
+  hostname = name.nodename;
+
+  umask(0022);
+  mr_init();
+
+  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.
+   */
+  if ((p = config_lookup("user")))
+    {
+      struct passwd *pw;
+      pw = getpwnam(p);
+      if (!pw)
+       {
+         com_err(whoami, errno, "Unable to find user %s\n", p);
+         exit(1);
+       }
+      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 ((p = config_lookup("chroot")))
+    {
+      if (chroot(p) < 0)
+       {
+         com_err(whoami, errno, "unable to chroot to %s", p);
+         exit(1);
+       }
+    }
+
+  com_err(whoami, 0, "got connection");
+
+  while (1)
+    {
+      char *cp, *str;
+      size_t len;
+      int code;
+
+      code = recv_string(conn, &str, &len);
+      if (code)
+       {
+         com_err(whoami, code, "receiving command");
+         close(conn);
+         exit(1);
+       }
+
+      cp = strchr(str, ' ');
+      if (cp)
+       *cp = '\0';
+      for (d = dispatch_table; d->str; d++)
+       {
+         if (!strcmp(d->str, str))
+           {
+             if (cp)
+               *cp = ' ';
+             (d->proc)(conn, str);
+             goto ok;
+           }
+       }
+      com_err(whoami, 0, "unknown request received: %s", str);
+      code = send_int(conn, MR_UNKNOWN_PROC);
+      if (code)
+       com_err(whoami, code, "sending UNKNOWN_PROC");
+    ok:
+      free(str);
+    }
+}
+
+int send_ok(int conn)
+{
+  return send_int(conn, 0);
+}
+
 /*
- * general scratch space -- useful for building
- * error messages et al...
+ * quit request:
+ *
+ * syntax:
+ * >>> quit
+ * <<< (int)0
+ * any arguments are ignored
+ *
+ * function:
+ *     closes connection from MR
  */
-char buf[BUFSIZ];
-err(code, fmt)
-     int code;
-     char *fmt;
+
+void quit(int conn, char *str)
 {
-     sprintf(buf, fmt, error_message(code));
-     sms_log_error(buf);
+  send_ok(conn);
+  close(conn);
+  com_err(whoami, 0, "Closing connection.");
+  exit(0);
 }
 
-main(argc, argv)
-     int argc;
-     char **argv;
+void fail(int conn, int err, char *msg)
 {
-     STRING str;
-     struct _dt *d;
-
-#ifdef DEBUG
-     gdb_debug(GDB_NOFORK);
-#endif /* DEBUG */
-
-     whoami = rindex(argv[0], '/');
-     if (whoami)
-        whoami++;
-     else
-        whoami = argv[0];
-
-     /* interpret arguments here */
-     if (argc != 1) {
-         fprintf(stderr, "Usage:  %s\n", whoami);
-         exit(1);
-     }
-     /* well, sort of... */
-
-     umask(0077);
-     sms_update_initialize();
-     init_smsU_err_tbl();
-
-     /* wait for connection */
-     gdb_init();
-     conn = create_forking_server(SERVICE_NAME, 0);
-     if (!conn) {
-         err(errno, "%s: can't get connection");
-         exit(1);
-     }
-     if (connection_status(conn) == CON_STOPPED) {
-        com_err(whoami, connection_errno(conn), ": can't get connection");
-        exit(1);
-     }
-
-     sms_log_info("got connection");
-     /* got a connection; loop forever */
-     while (1) {
-         register char *cp;
-         code = receive_object(conn, (char *)&str, STRING_T);
-         if (code) {
-              err(connection_errno(conn), "%s: receiving command");
-              sever_connection(conn);
-              exit(1);
-         }
-         cp = index(STRING_DATA(str), ' ');
-         if (cp)
-              *cp = '\0';
-         for (d = dispatch_table; d->str; d++) {
-             if (!strcmp(d->str, STRING_DATA(str))) {
-                 if (cp)
-                     *cp = ' ';
-#ifdef DEBUG
-                 printf("got request: %s\n", STRING_DATA(str));
-#endif /* DEBUG */
-                 (void)(d->proc)(STRING_DATA(str));
-                 goto ok;
-             }
-         }
-         sprintf(buf, "unknown request received: %s\n", STRING_DATA(str));
-         sms_log_error(buf);
-         code = send_int(SMSU_UNKNOWN_PROC);
-         if (code) {
-             err(connection_errno(conn), "%s: sending UNKNOWN_PROC");
-         }
-     ok:
-         string_free(&str);
-     }
+  com_err(whoami, err, msg);
+  close(conn);
+  exit(1);
 }
 
-int
-send_ok()
+void child_handler(int signal)
 {
-     static int zero = 0;
-     return((code = send_object(conn, (char *)&zero, INTEGER_T)));
+  int status;
+
+  while (waitpid(-1, &status, WNOHANG) > 0)
+    ;
+}
+
+static void syslog_com_err_proc(const char *progname, long code,
+                               const char *fmt, va_list args)
+{
+  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);
 }
This page took 0.042265 seconds and 4 git commands to generate.