/*
* MODULE IDENTIFICATION:
* $Header$
- * Copyright 1987 MIT Project Athena.
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
* DESCRIPTION:
* This code handles the actual distribution of data files
- * to servers in the SMS server-update program.
+ * to servers in the MOIRA server-update program.
* AUTHOR:
* Ken Raeburn (spook@athena.MIT.EDU),
* MIT Project Athena/MIT Information Systems.
* DEFINED VALUES:
* conn
- * update_info
- * sms_update_server
- * VERSION HISTORY:
- * $Log$
- * Revision 1.1 1987-08-22 17:53:46 wesommer
- * Initial revision
- *
+ * mr_update_server
*/
+#include <mit-copyright.h>
#include <stdio.h>
#include <strings.h>
-#include "gdb.h"
-#include <sys/stat.h>
-#include <sys/file.h>
+#include <gdb.h>
#include <sys/param.h>
-#include "update.h"
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <update.h>
#include <errno.h>
-#include "sms_update_int.h"
-#include "smsu_int.h"
+#include <dcm.h>
+#include <moira.h>
+#include <moira_site.h>
#include <krb.h>
-extern char *malloc(), *error_message();
-extern int errno;
-
-/* XXX */
-#include "kludge.h"
-/* XXX */
+extern char *malloc();
+extern int errno, dbg;
static char buf[BUFSIZ];
+static int code;
CONNECTION conn;
-struct update_desc *info;
-static int code;
/*
* FUNCTION:
* RETURN VALUE:
* void
* SIDE EFFECTS:
- * Initializes GDB library and SMSU error table.
+ * Initializes GDB library.
* PROBLEMS:
*
*/
-static
-void
+static void
initialize()
{
static int initialized = 0;
+
if (!initialized) {
gdb_init();
- init_smsU_err_tbl();
initialized++;
}
}
+
/*
* FUNCTION:
- * sms_update_server(info)
+ * mr_update_server(service, machine, target_path)
* DESCRIPTION:
- * Attempts to perform an update based on the information
- * contained in the data structure pointed to by "info".
- * Errors in performing the update are logged with the
- * sms_log* routines; the 'override' field may be updated
- * to cause updates to occur other than on the regular
- * schedule (generally to force an earlier retry).
+ * Attempts to perform an update to the named machine
+ * of the named service. The file DCM_DIR/service.out
+ * will be sent, then the file SMS_DIR/bin/service.sh,
+ * the the shell script will be executed.
* INPUT:
- * info->service_name
+ * service
* Name of service to be updated; used to find
- * the source data file in the SMS data directory.
- * info->host_name
- * info->target_path
+ * the source data file in the MR data directory.
+ * machine
+ * target_path
* Location to install the file.
- * info->enable
- * Must be non-zero.
- * info->instructions
- * Sequence of commands to execute on remote
- * machine to effect the installation.
- * OUTPUT:
- * info->last_time
- * Set to the current time if the update was
- * attempted.
- * info->success
- * Set to non-zero if the update succeeded, set
- * to zero otherwise.
- * info->override
- * Set to -1 if the update succeeds, to (possibly)
- * some other value otherwise.
* RETURN VALUE:
* int:
* Error code, or zero if no error was detected
*/
int
-sms_update_server(update_info, pathname)
- struct update_desc *update_info;
- char *pathname;
+mr_update_server(service, machine, target_path, instructions)
+char *service;
+char *machine;
+char *target_path;
+char *instructions;
{
-#define ASSERT(condition,amsg) \
- if (!(condition)) { msg = amsg; code = 0; goto local_error; }
+#define ASSERT(condition,stat,amsg) \
+ if (!(condition)) { com_err(whoami, stat, amsg); return(stat); }
+#define ASSERT2(condition,stat,amsg,arg1) \
+ if (!(condition)) { com_err(whoami, stat, amsg, arg1); return(stat); }
#define NONNULL(str) \
- (((str) != (char *)NULL) && ((size = strlen(str)) != 0))
-#define IO_ERROR(msg) \
- {log_priority=log_ERROR;com_err(whoami,connection_errno(conn),msg);goto io_error;}
+ (((str) != (char *)NULL) && (strlen(str) != 0))
- char *service_address;
- char *service_updated;
- char *msg;
- register char *cp;
- STRING string_data, string2;
- int size, num;
- int fd = -1;
- struct stat statb;
+ char *service_address, *service_updated, *pathname;
+ int on;
- /* variable initializations */
- code = 0;
- info = update_info;
- service_updated = (char *)NULL;
- STRING_DATA(string_data) = (char *)NULL;
-
- /* pessimism */
- info->success = 0;
-
/* some sanity checking of arguments while we build data */
- strcpy(buf, "???:???");
- ASSERT(NONNULL(info->host_name), "null host name");
- /* XXX -- check length here */
- strcpy(buf, info->host_name);
- for (cp = buf; *cp; cp++)
- ;
- strcpy(cp, ":???");
- ASSERT(NONNULL(info->service_name), "null service name");
- /* XXX -- check length here */
- strcpy(++cp, info->service_name);
- service_updated = malloc(strlen(buf)+1);
- /* XXX -- check allocation succeeded */
- strcpy(service_updated, buf);
- service_address = malloc(strlen(SERVICE_NAME)+strlen(info->host_name)+1);
- if (!service_address) {
- code = errno;
- info->override = -1;
- return(code);
- }
- strcpy(service_address, info->host_name);
- strcat(service_address, ":");
- strcat(service_address, SERVICE_NAME);
- ASSERT(info->enable, "server is disabled");
- ASSERT(NONNULL(info->target_path), "null target pathname");
- ASSERT(size < MAXPATHLEN, "target pathname too long");
- ASSERT(info->target_path[0] == '/', "non-absolute pathname supplied");
+ ASSERT(NONNULL(machine), MR_INTERNAL, " null host name");
+ ASSERT(NONNULL(service), MR_INTERNAL, " null service name");
+ ASSERT((strlen(machine) + strlen(service) + 2 < BUFSIZ), MR_ARG_TOO_LONG,
+ " machine and service names");
+ sprintf(buf, "%s:%s", machine, service);
+ service_updated = strsave(buf);
+ ASSERT(NONNULL(service_updated), MR_NO_MEM, " for service name");
+ ASSERT((strlen(machine)+strlen(SERVICE_NAME)+2 < BUFSIZ), MR_ARG_TOO_LONG,
+ " machine and update service name");
+ sprintf(buf, "%s:%s", machine, SERVICE_NAME);
+ service_address = strsave(buf);
+ ASSERT(NONNULL(service_address), MR_NO_MEM, " for service address");
+ ASSERT(NONNULL(target_path), MR_INTERNAL, " null target pathname");
+ ASSERT((strlen(target_path) < MAXPATHLEN), MR_ARG_TOO_LONG,
+ " target pathname");
+ ASSERT2(target_path[0] == '/', MR_NOT_UNIQUE,
+ " non-absolute pathname supplied \"%s\"", target_path);
+ sprintf(buf, "%s/%s.out", DCM_DIR, service);
+ pathname = strsave(buf);
+ ASSERT(NONNULL(pathname), MR_NO_MEM, " for pathname");
+ ASSERT(NONNULL(instructions), MR_NO_MEM, " for instructions");
+ ASSERT((strlen(instructions) < MAXPATHLEN), MR_ARG_TOO_LONG,
+ " instruction pathname");
initialize();
-
- string_alloc(&string2, BUFSIZ);
-
- sprintf(buf, "starting update for %s", service_updated);
- sms_log_info(buf);
-
- fd = open(pathname, O_RDONLY, 0);
- if (fd < 0) {
- code = errno;
- msg = pathname;
- goto local_error;
- }
- if (fstat(fd, &statb)) {
- code = errno;
- close(fd); fd = -1;
- strcat(buf, ": can't fstat:");
- strcat(buf, error_message(code));
- sms_log_error(buf);
- goto error_exit;
- }
- size = statb.st_size;
+ com_err(whoami, 0, "starting update for %s", service_updated);
/* open connection */
- conn = start_server_connection(service_address, 0);
- if (!conn) {
- com_err(whoami, 0, "can't connect to update %s", service_address);
- connect_failed:
- if (info->override<0 || info->override>INTERVAL_connection_failed)
- info->override = INTERVAL_connection_failed;
- return(0);
- }
- else if (connection_status(conn) == CON_STOPPED) {
- com_err(whoami, connection_errno(conn), ": can't connect to update %s",
- service_address);
- goto connect_failed;
+ gdb_Options |= GDB_OPT_KEEPALIVE;
+ conn = start_server_connection(service_address, "");
+ if (!conn || (connection_status(conn) == CON_STOPPED)) {
+ com_err(whoami, connection_errno(conn),
+ " can't connect to update %s", service_address);
+ return(MR_CANT_CONNECT);
}
-
/* send authenticators */
- code = send_auth();
+ code = send_auth(machine);
if (code) {
- sprintf(buf, "authorization attempt to %s failed: %s\n",
- service_updated, error_message(code));
+ com_err(whoami, code, " authorization attempt to %s failed",
+ service_updated);
goto update_failed;
}
- /* send file over */
- fd = open(pathname, O_RDONLY, 0);
- if (fd < 0) {
- code = errno;
- msg = pathname;
- goto local_error;
- }
- sprintf(STRING_DATA(string2), "XFER_002 %d %d %s",
- size, checksum_fd(fd), info->target_path);
- code = send_object(conn, (char *)&string2, STRING_T);
- if (code)
- IO_ERROR("%s: sending XFER_002 request");
- code = receive_object(conn, (char *)&num, INTEGER_T);
+ code = send_file(pathname, target_path, 0);
if (code)
- IO_ERROR("%s: getting reply from XFER_002 request");
- if (num) {
- sprintf(buf, "transfer request to %s (XFER_002) rejected: %s",
- service_updated, error_message(num));
- update_failed:
- sms_log_error(buf);
- /*
- * * if the update fails, something is probably wrong on
- * * the remote side; we'll have to let a maintainer
- * * take care of it. don't bother trying again any sooner
- * * than INTERVAL_update_failed minutes
- * */
- update_failed_1:
- if (info->override < INTERVAL_update_failed && info->override != -1)
- info->override = INTERVAL_update_failed;
- goto do_quit;
- }
- /* send actual data */
- code = send_file(pathname, size);
- if (code)
- goto update_failed_1;
- string_free(&string_data);
- close(fd);
-
+ goto update_failed;
+
/* send instructions for installation */
- strcpy(buf, "/tmp/sms-update.XXXXXX");
+ strcpy(buf, "/tmp/moira-update.XXXXXX");
mktemp(buf);
- fd = open(info->instructions, O_RDONLY, 0);
- if (fd < 0) {
- code = errno;
- log_priority = log_ERROR;
- com_err(whoami, code, ": can't open %s", info->instructions);
- send_quit();
- info->override = INTERVAL_local_error;
- goto error_exit;
- }
- if (fstat(fd, &statb)) {
- code = errno;
- close(fd);
- fd = -1;
- log_priority = log_ERROR;
- com_err(whoami, code, ": can't fstat %s", info->instructions);
- goto error_exit;
- }
- sprintf(STRING_DATA(string2), "XFER_002 %d %d %s",
- statb.st_size, checksum_fd(fd), buf);
- code = send_object(conn, (char *)&string2, STRING_T);
+ code = send_file(instructions, buf, 0);
if (code)
- IO_ERROR("%s: sending request for transfer of instructions");
- code = receive_object(conn, (char *)&num, INTEGER_T);
- if (code)
- IO_ERROR("%s: lost reply from installation script request");
- if (num) {
- com_err(whoami, num, ": transfer request rejected for %s", buf);
- goto update_failed_1;
- }
- code = send_file(info->instructions, statb.st_size);
- if (code)
- goto update_failed_1;
-
+ goto update_failed;
+
/* perform installation */
code = execute(buf);
if (code) {
- sprintf(buf, "installation of %s failed: %s", service_updated,
- error_message(code));
- sms_log_error(buf);
+ com_err(whoami, code, " installation of %s failed, code = %d",
+ service_updated, code);
+ goto update_failed;
}
- /* clear override timer and indicate success */
- info->override = -1;
- info->success = 1;
-
/* finished updates */
-do_quit:
+ code = MR_SUCCESS;
+
+ update_failed:
send_quit();
-
- /* fall through */
-EGRESS:
- code = 0;
-error_exit:
- info->last_time = time((long *)0);
- if (STRING_DATA(string2))
- string_free(&string2);
- if (STRING_DATA(string_data))
- string_free(&string_data);
conn = sever_connection(conn);
return(code);
-
-local_error:
- log_priority = log_ERROR;
- com_err(whoami, code, code ? ": %s" : "%s", msg);
- return(SMSU_INTERNAL_ERROR);
-
-io_error:
- sms_log_error(buf);
- if (info->override== -1 || info->override > INTERVAL_connection_lost)
- info->override = INTERVAL_connection_lost;
- goto EGRESS;
-
-#undef IO_ERROR
+
#undef NONNULL
#undef ASSERT
}
+
static
-send_auth()
+send_auth(host_name)
+char *host_name;
{
KTEXT_ST ticket_st;
KTEXT ticket = &ticket_st;
register int code;
int response;
- code = get_sms_update_ticket(info->host_name, ticket);
+ code = get_mr_update_ticket(host_name, ticket);
if (code) {
return(code);
}
if (response) {
return(response);
}
- return(0);
+ return(MR_SUCCESS);
}
static
code = receive_object(conn, (char *)&response, INTEGER_T);
if (code)
return(connection_errno(conn));
+ if (dbg & DBG_TRACE)
+ com_err(whoami, response, "execute returned %d", response);
if (response)
- return(response);
- return(0);
+ return(response);
+ return(MR_SUCCESS);
}
send_quit()