/* 
 * $Id: s_stddisp.c,v 1.2 91/05/03 03:07:20 qjb Exp Locker: qjb $
 * $Source: /afs/athena.mit.edu/astaff/project/qcs/src/RCS/s_stddisp.c,v $
 * $Author: qjb $
 *
 * This file contains some standard dispatchers that servers
 * can use to perform functions from the clients.
 */

#if !defined(lint) && !defined(SABER) || defined(RCS_HDRS)
static char *rcsid = "$Id: s_stddisp.c,v 1.2 91/05/03 03:07:20 qjb Exp Locker: qjb $";
#endif /* !lint && !SABER || RCS_HDRS */

#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

#include "qcs.h"
#include "qcs_private.h"

static char tmpbuf[BUFSIZ];


/*
 * If req == NULL or req->cmd[1] == NULL then we give status on all jobs.
 * otherwise, we give status on jobs that are owned by the user 
 * obtained by running kname_parse on cmd[1].
 */
void qcs_sd_status(qcs_client client, qcs_request *req)
{
    char name[ANAME_SZ + 1];
    char inst[INST_SZ + 1];
    char realm[REALM_SZ + 1];
    qcs_bool all_jobs = FALSE;
    char *jname;
    char *jinst;
    char *jrealm;

    bzero(name, sizeof(name));
    bzero(inst, sizeof(inst));
    bzero(realm, sizeof(realm));

    if ((req == NULL) || (req->cmd[1] == NULL)) {
	all_jobs = TRUE;
	sprintf(tmpbuf, "Displaying status for all jobs.");
    }
    else {
	if (kname_parse(name, inst, realm, req->cmd[1]) == KSUCCESS) 
	    sprintf(tmpbuf, "Displaying status for jobs owned by %s.", 
		    req->cmd[1]);
	else {
	    sprintf(tmpbuf, "Unable to parse name %s.", req->cmd[1]);
	    qcs_client_message(client, tmpbuf);
	    return;
	}
    }
    qcs_client_message(client, tmpbuf);

    if (all_jobs) {
	jname = NULL;
	jinst = NULL;
	jrealm = NULL;
    }
    else {
	jname = (char *)name;
	jinst = (char *)inst;
	jrealm = (char *)realm;
    }

    if (qcsi_show_active_jobs(client, jname, jinst, jrealm))
	qcsi_flush_client(&client);
    else if (qcsi_show_idle_clients(client, jname, jinst, jrealm))
	qcsi_flush_client(&client);
    qcs_client_message(client, "");
}

/*
 * It is okay for this to be called with req == NULL
 */
void qcs_sd_shutdown(qcs_client client, qcs_request *req)
{
    if (qcsi_is_server_shutdown()) {
	sprintf(tmpbuf, "Server shutdown request has already been received.");
	if (qcsi_client_error(client, tmpbuf)) 
	    qcsi_flush_client(&client);
	return;
    }

    /* Log that the server is being shut down. */
    sprintf(tmpbuf, "Server shutdown has been requested by %s",
	    qcsi_unparse_client(client));
    qcsi_log(tmpbuf);

    /* 
     * Shutdown listener so that we can get no new connections,
     * make it known that the server is going down, and flush
     * all jobs that are currently idle.
     */
    qcsi_shutdown_listener();
    qcs_client_message(client, "No longer accepting new connections.");
    qcsi_mark_server_shutdown(client);
    qcs_client_message(client, "Flusing all idle jobs.");
    qcsi_flush_idle_jobs();

    /* 
     * We must now protect this jobs so that it won't get flushed.
     * We do that so that we can continue to see status reports.
     */ 
    qcs_client_message(client, "Waiting for pending jobs to complete.");
}
