From 2a2a391475d7c4d5c50b836d72d95f4176c429fa Mon Sep 17 00:00:00 2001 From: danw Date: Fri, 5 Sep 1997 20:15:09 +0000 Subject: [PATCH] New DCM using embedded SQL instead of libmrglue --- dcm/Imakefile | 9 +- dcm/dcm.c | 451 -------------------------------------------------- dcm/dcm.pc | 382 ++++++++++++++++++++++++++++++++++++++++++ dcm/utils.c | 119 ------------- 4 files changed, 388 insertions(+), 573 deletions(-) delete mode 100644 dcm/dcm.c create mode 100644 dcm/dcm.pc delete mode 100644 dcm/utils.c diff --git a/dcm/Imakefile b/dcm/Imakefile index 826c0fd3..48643eff 100644 --- a/dcm/Imakefile +++ b/dcm/Imakefile @@ -8,9 +8,12 @@ # Imakefile for moira dcm. SRCDIR = $(SRCTOP)/dcm -SRCS= startdcm.c dcm.c utils.c -CODE=$(SRCS) -OBJS=dcm.o utils.o +SRCS= startdcm.c dcm.c +CODE= startdcm.c dcm.pc +OBJS=dcm.o +sqlrule() program(dcm, $(OBJS),,../update/moira_update.o $(CLIBS) $(SQL_LIB), ${PROGDIR}) program(startdcm, startdcm.o,,,${PROGDIR}) + +sqlfile(dcm) diff --git a/dcm/dcm.c b/dcm/dcm.c deleted file mode 100644 index 054ae0b0..00000000 --- a/dcm/dcm.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * The Data Control Manager for MOIRA. - * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * For copying and distribution information, see the file - * "mit-copyright.h". - * - * $Source$ - * $Author$ - * $Header$ - */ - -#ifndef lint -static char rcsid_dcm_c[] = "$Header$"; -#endif lint - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dcm.h" -#include "mit-copyright.h" -#include -#include - -extern int log_flags, errno; -int gqval(); -char *whoami; - -/* declared global so that we can get the current time from different places. */ -struct timeval tv; - - -main(argc, argv) -int argc; -char *argv[]; -{ - int i; - char **arg = argv; - char *qargv[3]; - char *s; - int status; - - whoami = argv[0]; - s = getenv("DEBUG"); - dbg = s ? atoi(s) : 0; - umask(UMASK); - log_flags = 0; - - setvbuf(stderr, NULL, _IOLBF, BUFSIZ); - setvbuf(stdout, NULL, _IOLBF, BUFSIZ); - - while(++arg - argv < argc) { - if (**arg == '-') - switch((*arg)[1]) { - case 'd': - dbg = atoi((*arg)[2]? *arg+2: *++arg); - break; - } - } - set_com_err_hook(dcm_com_err_hook); - - /* if /etc/nodcm exists, punt quietly. */ - if (!access(NODCMFILE, F_OK)) { - exit(1); - } - - if (status = mr_connect("")) { - com_err(whoami, status, " on mr_connect"); - leave("connect failed"); - } - - if (status = mr_auth("dcm")) { - com_err(whoami, status, " on \"authenticate\""); - leave("auth failed"); - } - - /* if DCM is not enabled, exit after logging */ - qargv[0] = "dcm_enable"; - if (status = mr_query("get_value", 1, qargv, gqval, &i)) { - com_err(whoami, status, " check dcm_enable"); - leave("query failed"); - } - if (i == 0) { - errno = 0; - leave("dcm_enable not set"); - } - - /* do it! */ - do_services(); - errno = 0; - leave(""); -} - - -/* Used by the get_value query when checking for dcm_enable. */ - -gqval(argc, argv, hint) -int argc; -char **argv; -int *hint; -{ - *hint = atoi(argv[0]); - return(UPCALL_STOP); -} - - -/* Used by qualified_get_server to make a list of servers to check */ - -qgetsv(argc, argv, sq) -int argc; -char **argv; -struct save_queue *sq; -{ - sq_save_data(sq, strsave(argv[0])); - return(UPCALL_CONT); -} - - -/* Used by get_server_info to record all of the returned information */ - -getsvinfo(argc, argv, sserv) -int argc; -char **argv; -struct service *sserv; -{ - sserv->service = strsave(argv[0]); - sserv->interval = atoi(argv[1]); - sserv->target = strsave(argv[2]); - sserv->script = strsave(argv[3]); - sserv->dfgen = atoi(argv[4]); - sserv->dfcheck = atoi(argv[5]); - sserv->type = strsave(argv[6]); - sserv->enable = atoi(argv[7]); - sserv->inprogress = atoi(argv[8]); - sserv->harderror = atoi(argv[9]); - sserv->errmsg = strsave(argv[10]); - return(UPCALL_STOP); -} - - -/* Scan the services and process any that need it. */ - -do_services() -{ - char *qargv[6]; - struct save_queue *sq, *sq_create(); - char *service, dfgen_prog[64], dfgen_cmd[128]; - struct service svc; - int status, lock_fd, ex, (*cstat)(); - struct timezone tz; - register char *p; - int waits; - struct sigaction action, prevaction; - - if (dbg & DBG_VERBOSE) - com_err(whoami, 0, "starting pass over services"); - - qargv[0] = "true"; - qargv[1] = "dontcare"; - qargv[2] = "false"; - sq = sq_create(); - if (status = mr_query("qualified_get_server", 3, qargv, qgetsv, sq)) { - com_err(whoami, status, " getting services"); - leave("query failed"); - } - while (sq_get_data(sq, &service)) { - for (p = service; *p; p++) - if (isupper(*p)) - *p = tolower(*p); - com_err(whoami, 0, "checking %s...", service); - qargv[0] = service; - sprintf(dfgen_prog, "%s/%s.gen", BIN_DIR, service); - if (!file_exists(dfgen_prog)) { - com_err(whoami, 0, "prog %s doesn't exist\n", dfgen_prog); - free(service); - continue; - } - sprintf(dfgen_cmd, "exec %s %s/%s.out", - dfgen_prog, DCM_DIR, service); - gettimeofday(&tv, &tz); - if (status = mr_query("get_server_info", 1, qargv, getsvinfo, &svc)) { - com_err(whoami, status, " getting service %s info, skipping to next service", service); - continue; - } - svc.service = strsave(service); - qargv[0] = strsave(service); - qargv[1] = itoa(svc.dfgen); - qargv[2] = itoa(svc.dfcheck); - qargv[3] = strsave("0"); - qargv[4] = itoa(svc.harderror); - qargv[5] = strsave(svc.errmsg); - if (svc.interval != 0) { - if (svc.interval * 60 + svc.dfcheck < tv.tv_sec) { - lock_fd = maybe_lock_update("@db@", service, 1); - if (lock_fd < 0) - goto free_service; - free(qargv[3]); - free(qargv[4]); - free(qargv[5]); - qargv[3] = strsave("1"); - qargv[4] = strsave("0"); - qargv[5] = strsave(""); - status = mr_query("set_server_internal_flags", 6, - qargv, scream, NULL); - if (status != MR_SUCCESS) { - com_err(whoami, status, " setting server state"); - goto free_service; - } - - com_err(whoami, status, " running %s", dfgen_prog); - - action.sa_flags = 0; - sigemptyset(&action.sa_mask); - action.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &action, &prevaction); - waits = system(dfgen_cmd); - sigaction(SIGCHLD, &prevaction, NULL); - if (WIFSIGNALED(waits)) { - status = MR_COREDUMP; - com_err(whoami, status, " %s exited on signal %d", - dfgen_prog, WTERMSIG(waits)); - } else if (WEXITSTATUS(waits)) { - /* extract the process's exit value */ - status = WEXITSTATUS(waits) + ERROR_TABLE_BASE_sms; - com_err(whoami, status, " %s exited", dfgen_prog); - } - - if (SOFT_FAIL(status)) { - free(qargv[5]); - qargv[5] = strsave(error_message(status)); - } else if (status == MR_NO_CHANGE) { - free(qargv[2]); - qargv[2] = itoa(tv.tv_sec); - svc.dfcheck = tv.tv_sec; - } else if (status == MR_SUCCESS) { - free(qargv[1]); - free(qargv[2]); - qargv[1] = itoa(tv.tv_sec); - qargv[2] = strsave(qargv[1]); - svc.dfcheck = svc.dfgen = tv.tv_sec; - } else { /* HARD_FAIL(status) */ - free(qargv[2]); - free(qargv[4]); - free(qargv[5]); - qargv[2] = itoa(tv.tv_sec); - svc.dfcheck = tv.tv_sec; - qargv[4] = itoa(status); - qargv[5] = strsave(error_message(status)); - critical_alert("DCM","DCM building config files for %s: %s", - service, qargv[5]); - } - free_service: - free(qargv[3]); - qargv[3] = strsave("0"); - status = mr_query("set_server_internal_flags", 6, - qargv, scream, NULL); - if (status) - com_err(whoami, status, " setting service state"); - close(lock_fd); - free(qargv[0]); - free(qargv[1]); - free(qargv[2]); - free(qargv[3]); - free(qargv[4]); - free(qargv[5]); - } - if (!strcmp(svc.type, "REPLICAT")) - ex = 1; - else - ex = 0; - lock_fd = maybe_lock_update("@db@", service, ex); - if (lock_fd >= 0) { - do_hosts(&svc); - close(lock_fd); - } - } - free(svc.service); - free(svc.target); - free(svc.script); - free(svc.type); - free(svc.errmsg); - free(service); - } - sq_destroy(sq); -} - - -/* Used by qualified_get_server_host to make a list of hosts to check */ - -qgethost(argc, argv, sq) -int argc; -char **argv; -struct save_queue *sq; -{ - sq_save_data(sq, strsave(argv[1])); - return(UPCALL_CONT); -} - - -/* Used by get_server_host_info to store all of the info about a host */ - -gethostinfo(argc, argv, shost) -int argc; -char **argv; -struct svrhost *shost; -{ - shost->service = strsave(argv[0]); - shost->machine = strsave(argv[1]); - shost->enable = atoi(argv[2]); - shost->override = atoi(argv[3]); - shost->success = atoi(argv[4]); - shost->inprogress = atoi(argv[5]); - shost->hosterror = atoi(argv[6]); - shost->errmsg = strsave(argv[7]); - shost->lasttry = atoi(argv[8]); - shost->lastsuccess = atoi(argv[9]); - shost->value1 = atoi(argv[10]); - shost->value2 = atoi(argv[11]); - shost->value3 = strsave(argv[12]); - return(UPCALL_STOP); -} - - -/* Scans all of the hosts for a particular service, and processes them. */ - -do_hosts(svc) -struct service *svc; -{ - char *argv[9], *machine; - int status, lock_fd; - struct save_queue *sq; - struct svrhost shost; - - sq = sq_create(); - argv[0] = svc->service; - argv[1] = "TRUE"; - argv[2] = argv[3] = argv[4] = "DONTCARE"; - argv[5] = "FALSE"; - status = mr_query("qualified_get_server_host", 6, argv, qgethost, sq); - if (status == MR_NO_MATCH) { - return; - } else if (status) { - com_err(whoami, status, " getting server_hosts for %s", svc->service); - return; - } - while (sq_get_data(sq, &machine)) { - if (dbg & DBG_TRACE) - com_err(whoami, 0, "checking %s...", machine); - argv[1] = machine; - status = mr_query("get_server_host_info", 2, argv, - gethostinfo, &shost); - if (status) { - com_err(whoami,status, " getting server_host_info for %s", machine); - goto free_mach; - } - if (!shost.enable || shost.hosterror || - (shost.success && !shost.override && - shost.lastsuccess >= svc->dfgen)) { - if (dbg & DBG_TRACE) - com_err(whoami, 0, "not updating %s:%s", svc->service, machine); - goto free_mach; - } - - lock_fd = maybe_lock_update(machine, svc->service, 1); - if (lock_fd < 0) - goto free_mach; - argv[0] = svc->service; - argv[1] = machine; - argv[2] = argv[3] = argv[5] = "0"; - argv[4] = "1"; - argv[6] = strsave(""); - argv[7] = itoa(tv.tv_sec); - argv[8] = itoa(shost.lastsuccess); - status = mr_query("set_server_host_internal", 9, argv, scream, NULL); - if (status != MR_SUCCESS) { - com_err(whoami,status," while setting internal state for %s:%s", - svc->service, machine); - goto free_mach; - } - status = mr_update_server(svc->service, machine, svc->target, - svc->script); - if (status == MR_SUCCESS) { - argv[2] = argv[4] = "0"; - argv[3] = "1"; - free(argv[8]); - argv[8] = itoa(tv.tv_sec); - } else if (SOFT_FAIL(status)) { - argv[4] = "0"; - free(argv[6]); - argv[6] = strsave(error_message(status)); - } else { /* HARD_FAIL */ - argv[2] = itoa(shost.override); - argv[4] = "0"; - argv[5] = itoa(status); - free(argv[6]); - argv[6] = strsave(error_message(status)); - critical_alert("DCM", "DCM updating %s:%s: %s", - machine, svc->service, argv[6]); - if (!strcmp(svc->type, "REPLICAT")) { - char *qargv[6]; - - svc->harderror = status; - svc->errmsg = strsave(argv[6]); - qargv[0] = strsave(svc->service); - qargv[1] = itoa(svc->dfgen); - qargv[2] = itoa(svc->dfcheck); - qargv[3] = strsave("0"); - qargv[4] = itoa(svc->harderror); - qargv[5] = strsave(svc->errmsg); - status = mr_query("set_server_internal_flags", - 6, qargv, scream, NULL); - if (status) - com_err(whoami, status, " setting service state again"); - free(qargv[0]); - free(qargv[1]); - free(qargv[2]); - free(qargv[3]); - free(qargv[4]); - free(qargv[5]); - close(lock_fd); - status = mr_query("set_server_host_internal", - 9, argv,scream,NULL); - free(argv[2]); - free(argv[5]); - if (status) - com_err(whoami, status, " setting host state again"); - return(-1); - } - } - close(lock_fd); - status = mr_query("set_server_host_internal", 9, argv, scream, NULL); - if (status) - com_err(whoami, status, " setting host state again"); -/* free(argv[2]); - free(argv[5]); */ - free_mach: - free(machine); - close(lock_fd); - } - return(0); -} diff --git a/dcm/dcm.pc b/dcm/dcm.pc new file mode 100644 index 00000000..17bf2c47 --- /dev/null +++ b/dcm/dcm.pc @@ -0,0 +1,382 @@ +/* + * The Data Control Manager for MOIRA. + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * For copying and distribution information, see the file + * "mit-copyright.h". + * + * $Source$ + * $Author$ + * $Header$ + */ + +#ifndef lint +static char rcsid_dcm_c[] = "$Header$"; +#endif lint + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +EXEC SQL INCLUDE sqlca; +EXEC SQL WHENEVER SQLERROR DO dbmserr(); + +#define SQL_NO_MATCH 1403 +#define SOFT_FAIL(x) (((x) == MR_NO_MEM) || ((x) == MR_CANT_CONNECT) || ((x) == MR_CCONFIG) || ((x) == MR_DEADLOCK) || ((x) == MR_BUSY) || ((x) == MR_ABORT)) + +char whobuf[256], *whoami=whobuf, *db="moira"; +extern CONNECTION conn; + +int main(argc, argv) +int argc; +char *argv[]; +{ + int i; + EXEC SQL BEGIN DECLARE SECTION; + char buf[16], *name; + int enable; + EXEC SQL END DECLARE SECTION; + struct save_queue *sq; + int status; + + if (strchr(argv[0], '/')) strcpy(whoami, strrchr(argv[0], '/')+1); + else strcpy(whoami, argv[0]); + umask(7); + + setvbuf(stderr, NULL, _IOLBF, BUFSIZ); + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); + + initialize_sms_error_table(); + initialize_krb_error_table(); + + /* if services were specified on the command line, do just those ones */ + if (argc > 1) { + for (i = 1; i < argc; i++) { + if (generate_service(argv[i], 1)) + do_hosts(argv[i]); + } + exit(0); + } + + /* if DCM is not enabled, exit after logging */ + if (!access(NODCMFILE, F_OK)) { + printf("/etc/nodcm exists -- exiting\n"); + exit(1); + } + + EXEC SQL CONNECT :db IDENTIFIED BY :db; + + EXEC SQL SELECT value INTO :enable FROM numvalues + WHERE name='dcm_enable'; + if (enable == 0) { + printf("dcm_enable not set -- exiting\n"); + exit(1); + } + + /* fetch list of services */ + EXEC SQL DECLARE csr_svc CURSOR FOR SELECT LOWER(name) FROM servers + WHERE enable=1 AND harderror=0 AND update_int>0; + EXEC SQL OPEN csr_svc; + sq = sq_create(); + while(1) { + EXEC SQL FETCH csr_svc INTO :buf; + if (sqlca.sqlcode) break; + + sq_save_data(sq, strdup(strtrim(buf))); + } + EXEC SQL CLOSE csr_svc; + /* we will repeatedly open and close the db since it seems to get + upset if you keep it open across a fork */ + EXEC SQL COMMIT RELEASE; + + /* Now run through list */ + while (sq_get_data(sq, &name)) { + if (generate_service(name, 0)) { + switch (fork()) { + case -1: + fprintf(stderr, + "dcm: could not fork to for service %s -- exiting", + name); + exit(1); + case 0: + sprintf(strchr(whoami, '\0'), " (%s)", name); + do_hosts(name); + com_err(whoami, 0, "exiting"); + exit(0); + default: + break; + } + } + } + + /* wait for children */ + while (waitpid(0, &status, 0) > 0) ; + com_err(whoami, 0, "exiting"); +} + +int generate_service(char *name, int force) +{ + EXEC SQL BEGIN DECLARE SECTION; + int interval, dfcheck, status; + time_t now; + char *errmsg; + EXEC SQL END DECLARE SECTION; + char dfgen_prog[64], dfgen_cmd[128]; + struct sigaction action, prevaction; + int waits; + + EXEC SQL CONNECT :db IDENTIFIED BY :db; + + EXEC SQL SELECT update_int, dfcheck INTO :interval, :dfcheck + FROM servers WHERE name=UPPER(:name); + if (sqlca.sqlcode == SQL_NO_MATCH) { + com_err(whoami, 0, "No such service `%s'", name); + EXEC SQL COMMIT RELEASE; + return 0; + } + + time(&now); + + if ((interval * 60 + dfcheck < now) || force) { + sprintf(dfgen_prog, "%s/%s.gen", BIN_DIR, name); + if (access(dfgen_prog, F_OK) != 0) { + com_err(whoami, 0, "prog %s doesn't exist", dfgen_prog); + EXEC SQL COMMIT RELEASE; + return 0; + } + sprintf(dfgen_cmd, "exec %s %s/%s.out", dfgen_prog, DCM_DIR, name); + com_err(whoami, 0, "running %s", dfgen_prog); + + EXEC SQL UPDATE servers SET inprogress=1 + WHERE name=UPPER(:name); + + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &action, &prevaction); + waits = system(dfgen_cmd); + sigaction(SIGCHLD, &prevaction, NULL); + if (WIFSIGNALED(waits)) { + status = MR_COREDUMP; + com_err(whoami, status, " %s exited on signal %d", + dfgen_prog, WTERMSIG(waits)); + } else if (WEXITSTATUS(waits)) { + /* extract the process's exit value */ + status = WEXITSTATUS(waits) + ERROR_TABLE_BASE_sms; + if (status != MR_NO_CHANGE) + com_err(whoami, status, "in %s", dfgen_prog); + } else status = MR_SUCCESS; + + if (status == MR_SUCCESS) { + EXEC SQL UPDATE servers SET dfgen = :now, dfcheck = :now, + inprogress = 0 WHERE name=UPPER(:name); + EXEC SQL COMMIT RELEASE; + return 1; + } else if (status == MR_NO_CHANGE) { + EXEC SQL UPDATE servers SET dfcheck = :now, inprogress = 0 + WHERE name=UPPER(:name); + } else if (SOFT_FAIL(status)) { + errmsg = error_message(status); + EXEC SQL UPDATE servers SET errmsg = :errmsg, inprogress = 0 + WHERE name=UPPER(:name); + } else { /* HARD_FAIL(status) */ + errmsg = error_message(status); + EXEC SQL UPDATE servers SET dfcheck = :now, harderror = :status, + errmsg = :errmsg, inprogress = 0 WHERE name=UPPER(:name); +#if 0 + critical_alert("DCM","DCM building config files for %s: %s", + name, errmsg); +#endif + } + } + EXEC SQL COMMIT RELEASE; + return 0; +} + +void do_hosts(char *service) +{ + EXEC SQL BEGIN DECLARE SECTION; + char type[16], host[73], target[64], script[128], *errmsg; + int status = 0, mid, dfgen, replicated; + time_t now; + EXEC SQL END DECLARE SECTION; + + time(&now); + gdb_init(); + + EXEC SQL CONNECT :db IDENTIFIED BY :db; + + EXEC SQL SELECT dfgen, type, target_file, script + INTO :dfgen, :type, :target, :script + FROM servers WHERE name=UPPER(:service); + replicated = !strncmp(type, "REPLICAT", 8); + + EXEC SQL DECLARE csr_hst1 CURSOR FOR + SELECT m.name FROM machine m, serverhosts sh + WHERE sh.service=UPPER(:service) AND sh.enable=1 AND sh.hosterror=0 + AND sh.lts<:dfgen AND sh.mach_id=m.mach_id + FOR UPDATE OF sh.inprogress, sh.hosterror, sh.hosterrmsg; + EXEC SQL OPEN csr_hst1; + + while (1) { + EXEC SQL FETCH csr_hst1 INTO :host; + if (sqlca.sqlcode == SQL_NO_MATCH) break; + + com_err(whoami, 0, "sending %s data to %s", service, strtrim(host)); + EXEC SQL UPDATE serverhosts SET inprogress = 1 + WHERE CURRENT OF csr_hst1; + status = dcm_send_file(service, host, strtrim(target)); + if (status) { + errmsg = error_message(status); + EXEC SQL UPDATE serverhosts SET hosterrmsg = :errmsg, + inprogress = 0 WHERE CURRENT OF csr_hst1; + if (!SOFT_FAIL(status)) { + EXEC SQL UPDATE serverhosts SET hosterror = :status + WHERE CURRENT OF csr_hst1; +#if 0 + critical_alert("DCM", "DCM updating %s:%s: %s", + service, host, errmsg); +#endif + } + + if (replicated) break; + } + } + EXEC SQL CLOSE csr_hst1; + + if (status == MR_SUCCESS || !replicated) { + EXEC SQL DECLARE csr_hst2 CURSOR FOR + SELECT m.name FROM machine m, serverhosts sh + WHERE sh.service=UPPER(:service) AND sh.inprogress=1 + AND sh.mach_id=m.mach_id + FOR UPDATE OF sh.hosterror, sh.hosterrmsg, sh.inprogress; + EXEC SQL OPEN csr_hst2; + + while (1) { + EXEC SQL FETCH csr_hst2 INTO :host; + if (sqlca.sqlcode == SQL_NO_MATCH) break; + + com_err(whoami, 0, "executing instructions on %s", strtrim(host)); + status = dcm_execute(service, host, strtrim(script)); + if (status) { + errmsg = error_message(status); + EXEC SQL UPDATE serverhosts SET hosterrmsg = :errmsg, + inprogress = 0 WHERE CURRENT OF csr_hst2; + if (!SOFT_FAIL(status)) { + EXEC SQL UPDATE serverhosts SET hosterror = :status + WHERE CURRENT OF csr_hst2; +#if 0 + critical_alert("DCM", "DCM updating %s:%s: %s", + service, host, errmsg); +#endif + } + + if (replicated) { + /* We're giving up, so clear the inprogress flag on + any hosts in this service we haven't gotten to yet */ + EXEC SQL UPDATE serverhosts SET inprogress = 0 + WHERE service=UPPER(:service); + break; + } + } else { + EXEC SQL UPDATE serverhosts SET inprogress=0, lts=:now + WHERE CURRENT OF csr_hst2; + } + } + EXEC SQL CLOSE csr_hst2; + } + + if (status && replicated) { + EXEC SQL UPDATE servers SET harderror = :status, errmsg = :errmsg + WHERE name = UPPER(:service); + } + + EXEC SQL COMMIT RELEASE; +} + +int dcm_send_file(char *service, char *host, char *target) +{ + char addr[256], data[MAXPATHLEN]; + int code; + + sprintf(addr, "%s:moira_update", host); + conn = start_server_connection(addr, ""); + if (!conn || (connection_status(conn) == CON_STOPPED)) { + com_err(whoami, connection_errno(conn), "can't connect to %s", addr); + return MR_CANT_CONNECT; + } + + code = send_auth(host); + if (code) { + com_err(whoami, code, "authenticating to %s", host); + goto done; + } + + sprintf(data, "%s/%s.out", DCM_DIR, service); + code = send_file(data, target, 1); + if (code == MR_UNKNOWN_PROC) code = send_file(data, target, 0); + if (code) com_err(whoami, code, "sending data to %s", host); + +done: + send_quit(); + sever_connection(conn); + return(code); +} + +int dcm_execute(char *service, char *host, char *script) +{ + char addr[256], inst[MAXPATHLEN]; + int code; + + sprintf(addr, "%s:moira_update", host); + conn = start_server_connection(addr, ""); + if (!conn || (connection_status(conn) == CON_STOPPED)) { + com_err(whoami, connection_errno(conn), "can't connect to %s", addr); + return MR_CANT_CONNECT; + } + + code = send_auth(host); + if (code) { + com_err(whoami, code, "authenticating to %s", host); + goto done; + } + + sprintf(inst, "/tmp/moira-update.XXXXXX"); + mktemp(inst); + code = send_file(script, inst, 0); + if (code) { + com_err(whoami, code, "sending instructions to %s", host); + goto done; + } + + code = execute(inst); + if (code) com_err(whoami, code, "executing instructions on %s", host); + +done: + send_quit(); + sever_connection(conn); + return(code); +} + +void dbmserr(void) +{ + EXEC SQL BEGIN DECLARE SECTION; + char err_msg[256]; + EXEC SQL END DECLARE SECTION; + int bufsize=256, msglength=0; + + sqlglm(err_msg, &bufsize, &msglength); + err_msg[msglength]=0; + com_err(whoami, 0, "Encountered SQL error:\n%s", err_msg); + com_err(whoami, 0, "exiting"); + exit(1); +} diff --git a/dcm/utils.c b/dcm/utils.c deleted file mode 100644 index c0c4501b..00000000 --- a/dcm/utils.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * $Source$ - * $Author$ - * $Header$ - * - * - * Utility functions used by the DCM. - * - * (c) Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * For copying and distribution information, please see the file - * . - */ - -#ifndef lint -static char *rcsid_utils_c = "$Header$"; -#endif lint - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dcm.h" - - -int dbg = 0; -int log_flags; - -extern char *strsave(); - -void dcm_com_err_hook(whoami, code, fmt, pvar) - char *whoami; - int code; - char *fmt; - caddr_t pvar; -{ - if (whoami) { - fputs(whoami, stderr); - fputs(": ", stderr); - } - if (code) { - fputs(error_message(code), stderr); - } - if (fmt) { - _doprnt(fmt, pvar, stderr); - } - putc('\n', stderr); - fflush(stderr); -} - -void leave(s) -char *s; -{ - extern int errno; - - if (*s) - com_err(whoami, errno, "%s: exiting", s); - else - com_err(whoami, errno, "exiting"); - - exit(errno); -} - -void scream(argc, argv, hint) -int argc; -char **argv; -int hint; -{ - leave("Programmer botch"); -} - - -char *itoa(i) -int i; -{ - char buf[20]; - - sprintf(buf, "%d", i); - return(strsave(buf)); -} - - -char *tkt_string() -{ - return("/tmp/tkt_dcm"); -} - - -int maybe_lock_update(host, service, exclusive) -char *host, *service; -int exclusive; -{ - char lock[BUFSIZ]; - int fd; - flock_t fl; - - sprintf(lock, "%s/%s.%s", LOCK_DIR, host, service); - fl.l_type = exclusive ? F_WRLCK : F_RDLCK; - fl.l_whence = fl.l_start = fl.l_len = 0; - if ((fd = open(lock, O_TRUNC | O_CREAT | O_RDWR, 0)) < 0) - com_err(whoami, errno, ": maybe_lock_update: opening %s", lock); - else if (fcntl(fd, F_SETLK, &fl) != 0) { - if (errno != EAGAIN) - com_err(whoami, errno, ": maybe_lock_update: flock"); - else if (dbg & DBG_VERBOSE) - com_err(whoami, 0, "%s already locked\n", lock); - close(fd); - return -1; - } else if (dbg & DBG_VERBOSE) - com_err(whoami, 0, "%s now locked\n", lock); - return fd; -} -- 2.45.2