/*
 * Script to display the status of a queue given by the path_info argument.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sjcdef.h>		/* VMS $SNDJBC codes */
#include <quidef.h>		/* VMS $GETQUI codes */
#include "cgilib.h"

struct item_list {
    short length, code;
    void *bufaddr;
    int *retlen;
};
struct jbc_iosb { int status, reserved; };
#define SET_ITEM(item,len,cod,addr,ret) item.length=(len); item.code=(cod);\
	item.bufaddr=(addr); item.retlen=((int *) ret)

#define SEND_JBC(func,itmlst,iosb) SYS$SNDJBCW(0,(func),0,(itmlst),(iosb),0,0)
#define GET_QUI(func,ctx,itmlst,iosb) SYS$GETQUIW(0,(func),(ctx),(itmlst),\
	(iosb),0,0)
int SYS$SNDJBCW(), SYS$GETQUIW();

static struct { int mask; char *name; } state_names[] = {
   { QUI$M_QUEUE_BUSY, "busy" }, {QUI$M_QUEUE_DISABLED, "disabled"},
   { QUI$M_QUEUE_IDLE, "idle" }, { QUI$M_QUEUE_PAUSED, "paused" },
   { QUI$M_QUEUE_PAUSING, "pausing" }, { QUI$M_QUEUE_RESUMING, "resuming" },
   { QUI$M_QUEUE_STALLED, "stalled" }, { QUI$M_QUEUE_STARTING, "starting" },
   { QUI$M_QUEUE_STOPPED, "stopped" }, { QUI$M_QUEUE_STOPPING, "stoping" },
   { 0, "??unknown??" } };

static void error_abort ( char *reason )
{
    cgi_printf ( "Content-type: text/html\n" );
    cgi_printf ( "<HTML><HEAD><TITLE>display queue failure</TITLE></HEAD>\n");
    cgi_printf ( "<BODY>><H2>Script failure!</H2><P>%s<HR>\n", reason );
    exit ( 1 );
}

static void get_script_url ( char *url, int size )
{
    /*
     * Retrieve host and script name and return URL http://host/script/
     */
    char *host, *script, *port, *port_delim;
    host = cgi_info ( "HTTP_HOST" );
    port = "";
    port_delim = "";
    if ( !host ) {
	host = cgi_info ( "SERVER_NAME" );
        port = cgi_info ( "SERVER_PORT" );
        if ( strcmp ( port, "80" ) == 0 ) port = "";
        else port_delim = ":";
    }
    script = cgi_info ( "SCRIPT_NAME" );
    size = size - strlen(host) - strlen(port) - strlen(port_delim);
    if ( size > 8 ) sprintf ( url, "http://%s%s%s%s/", host, port_delim, port,
	script );
    else strcpy ( url, "" );
}
/***********************************************************************/
/* List all queues matching wildcard specification and show status.
 */
void show_queue_list ( char *qspec, const char *base_url )
{
    struct item_list item[10];
    int status, i;
    long context, queue_status, search_flags, pending_count;
    char queue_name[32], processor[32];
    int qn_len;
    struct jbc_iosb iosb;
    /*
     * Send CGI header.
     */
     cgi_printf ( "Content-type: text/html\n\n<HTML><HEAD>\n" );
    cgi_printf ( "<TITLE>Queue list</TITLE></HEAD><BODY>\n" );
    cgi_printf ( "<H2>Show queue %s</H2>\n<DL>\n", qspec );
    /*
     * Set up for scan.
     */
    context = -1;
    qn_len = 0;
    search_flags = QUI$M_SEARCH_ALL_JOBS | QUI$M_SEARCH_PRINTER |
	QUI$M_SEARCH_SERVER;
    pending_count;
    SET_ITEM ( item[0], sizeof(queue_name)-1, QUI$_QUEUE_NAME,
	queue_name,&qn_len);
    SET_ITEM ( item[1], sizeof(queue_status), QUI$_QUEUE_STATUS,
	&queue_status, 0);
    SET_ITEM ( item[2], strlen(qspec), QUI$_SEARCH_NAME, qspec, 0 );
    SET_ITEM ( item[3], sizeof(search_flags), QUI$_SEARCH_FLAGS,
	&search_flags, 0 );
    SET_ITEM ( item[4], sizeof(pending_count), QUI$_PENDING_JOB_COUNT,
	&pending_count, 0 );
    SET_ITEM ( item[5], 0, 0, 0, 0 );
    /*
     * List the queues.
     */
    for ( i = 0; i < 100000; i++ ) {
	int j;
	status = GET_QUI ( QUI$_DISPLAY_QUEUE, &context, item, &iosb );
	if ( (status&1) == 0 ) {
	    cgi_printf ( "**error*** code: %d<P>\n", status );
	    break;
	}
	if ( (iosb.status&1) == 0 ) break;

	queue_name[qn_len] = '\0';
	for ( j = 0; state_names[j].mask; j++ ) {
	    if ( state_names[j].mask & queue_status ) break;
	}
	cgi_printf("<DT><A HREF=\"%s\">%s</A></DT>\n<DD>%s",
		queue_name, queue_name,  state_names[j].name );
	if ( pending_count > 0 ) cgi_printf ( ", %d pending job%s",
	    pending_count, pending_count == 1 ? "" : "s" );
	cgi_printf ( "</DD>\n");
    }
    /*
     * add html trailer.
     */
    cgi_printf ( "</DL><BR><HR><BR>final getqui status: %d</BODY></HTML>\n",
	status );
    GET_QUI ( QUI$_CANCEL_OPERATION, &context, 0, &iosb );
}
/***********************************************************************/
/* List all queues matching wildcard specification and show status.
 */
static void show_queue_entries ( 
	const char *base_url, const char *queue_name, const char *arg )
{
    cgi_printf ( "Content-type: text/plain\n\ndo later\n" );
}
/***********************************************************************/

int main ( int argc, char **argv )
{
    int status;
    char *path_info;
    char base_url[256];
    /*
     * Initialize cgi environment and get argument.
     */
    status = cgi_init ( argc, argv );
    if ( (status&1) == 0 ) return status;
    path_info = cgi_info ( "PATH_INFO" );
    if ( !path_info ) {
	error_abort ( "Unexpected absence of PATH_INFO variable\n");
    }
    /*
     * Interpret the path_info argument
     */
    get_script_url ( base_url, sizeof(base_url) );
    if ( !*path_info ) {
	/*
	 * Missing trailing slash, redirect
	 */
	cgi_printf ( "Location: %s\n\n\n", base_url );

    } else if ( strcmp("/",path_info) == 0 ) {
	/*
	 * Null, show all queues with links.
	 */
	show_queue_list ( "HP*", base_url );

    } else {
	/*
	 * First element is queue name.
	 */
	char target[32], *arg;
	int j;
	arg = "";
	for ( j = 0; j < 31; j++ ) {
	    target[j] = path_info[j+1];
	    if ( !target[j] ) break;
	    if ( target[j] == '/' ) {
		arg = &path_info[j+2];
		break;
	    }
	}
	target[j] = '\n';
	show_queue_entries ( base_url, target, arg );
    }
    return 1;
}
