* $Source$
* $Header$
*/
+/* (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 lint
+#include <mit-copyright.h>
#include <stdio.h>
-#include "gdb.h"
+#include <gdb.h>
#include <errno.h>
-#include <strings.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>
+#endif
#include "update.h"
-#include "sms_update_int.h"
-#include "smsu_int.h"
-/* XXX */
-#include "kludge.h"
-/* XXX */
-
-extern int auth_001(), exec_001(), inst_001(), xfer_001();
-extern int xfer_002(), exec_002();
+extern int auth_001(), inst_001();
+extern int xfer_002(), xfer_003(), exec_002();
extern int sync_proc(), quit();
+extern char *config_lookup();
extern void gdb_debug();
-extern int exit(), abort(), errno;
+extern int abort(), errno;
+#ifndef sun
+extern int exit();
+#endif
+extern STRING instructions;
CONNECTION conn;
int code;
char *whoami;
+int have_authorization = 0;
+int have_file = 0;
+int have_instructions = 0;
+int done = 0;
+int uid = 0;
+
#define send_int(n) \
(_send_int=(n),send_object(conn,(char *)&_send_int,INTEGER_T))
int _send_int;
} dispatch_table[] = {
{ "INST_001", inst_001 },
{ "AUTH_001", auth_001 },
- { "XFER_001", xfer_001 },
- { "EXEC_001", exec_001 },
{ "XFER_002", xfer_002 },
+ { "XFER_003", xfer_003 },
{ "EXEC_002", exec_002 },
{ "quit", quit },
{ (char *)NULL, abort }
};
-/*
- * general scratch space -- useful for building
- * error messages et al...
- */
+/* general scratch space -- useful for building error messages et al... */
char buf[BUFSIZ];
-err(code, fmt)
- int code;
- char *fmt;
-{
- sprintf(buf, fmt, error_message(code));
- sms_log_error(buf);
-}
+
main(argc, argv)
int argc;
{
STRING str;
struct _dt *d;
+ char *p;
+ int n;
#ifdef DEBUG
gdb_debug(GDB_NOFORK);
#endif /* DEBUG */
- whoami = rindex(argv[0], '/');
+ whoami = strrchr(argv[0], '/');
if (whoami)
whoami++;
else
fprintf(stderr, "Usage: %s\n", whoami);
exit(1);
}
- /* well, sort of... */
- umask(0077);
- sms_update_initialize();
- init_smsU_err_tbl();
+#ifndef DEBUG
+ if (!config_lookup("nofork")) {
+ if (fork())
+ exit(0);
+#ifdef POSIX
+ setsid();
+#else
+ n = open("/dev/tty", O_RDWR|FNDELAY);
+ if (n > 0) {
+ (void) ioctl(n, TIOCNOTTY, (char *)NULL);
+ (void) close(n);
+ }
+#endif
+ } else
+ gdb_debug(GDB_NOFORK);
+#endif
+
+ umask(0022);
+ initialize_sms_error_table();
+ initialize_krb_error_table();
+ mr_update_initialize();
/* wait for connection */
gdb_init();
- conn = create_forking_server(SERVICE_NAME, 0);
+ /* 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")) == NULL)
+ p = SERVICE_NAME;
+ conn = create_forking_server(p, 0);
+
+ /* 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 == 0) {
+ com_err(whoami, errno, "Unable to find user %s\n", p);
+ exit(1);
+ }
+ uid = pw->pw_uid;
+ }
+
+ /* 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);
+ }
+ }
+
if (!conn) {
- err(errno, "%s: can't get connection");
- exit(1);
+ 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);
}
- sms_log_info("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);
if (code) {
- err(connection_errno(conn), "%s: receiving command");
- sever_connection(conn);
- exit(1);
+ com_err(whoami, connection_errno(conn), "receiving command");
+ sever_connection(conn);
+ exit(1);
}
- cp = index(STRING_DATA(str), ' ');
+ cp = strchr(STRING_DATA(str), ' ');
if (cp)
*cp = '\0';
for (d = dispatch_table; d->str; d++) {
}
}
sprintf(buf, "unknown request received: %s\n", STRING_DATA(str));
- sms_log_error(buf);
- code = send_int(SMSU_UNKNOWN_PROC);
+ mr_log_error(buf);
+ code = send_int(MR_UNKNOWN_PROC);
if (code) {
- err(connection_errno(conn), "%s: sending UNKNOWN_PROC");
+ com_err(whoami, connection_errno(conn), "sending UNKNOWN_PROC");
}
ok:
string_free(&str);
static int zero = 0;
return((code = send_object(conn, (char *)&zero, INTEGER_T)));
}
+
+
+initialize()
+{
+ /* keep have_authorization around */
+ have_file = 0;
+ have_instructions = 0;
+ done = 0;
+ if (STRING_DATA(instructions) != (char *)NULL)
+ string_free(&instructions);
+}
+
+
+/*
+ * quit request:
+ *
+ * syntax:
+ * >>> quit
+ * <<< (int)0
+ * any arguments are ignored
+ *
+ * function:
+ * closes connection from MR
+ */
+int
+quit(str)
+ char *str;
+{
+#ifdef lint
+ str = (char *)NULL;
+#endif /* lint */
+ (void) send_ok();
+ sever_connection(conn);
+ mr_log_info("Closing connection.");
+ return(exit(0));
+}
+
+
+/*
+ * lose(msg)
+ *
+ * put <msg> to log as error, break connection, and exit
+ */
+
+lose(msg)
+ char *msg;
+{
+ com_err(whoami, code, msg);
+ if (conn)
+ sever_connection(conn);
+ exit(1);
+}
+
+/*
+ * report_error(msg)
+ *
+ * send back (external) <code>; if error, punt big with <lose(msg)>
+ */
+
+report_error(msg)
+ char *msg;
+{
+ code = send_object(conn, (char *)&code, INTEGER_T);
+ if (code) {
+ code = connection_errno(conn);
+ lose(msg);
+ }
+}
+
+/*
+ * reject_call(c)
+ *
+ * set (external) <code> to <c> and call <report_error>
+ */
+
+reject_call(c)
+ int c;
+{
+ code = c;
+ report_error("call rejected");
+}