#include <stdio.h>
#include <string.h>
#include <starlet.h>
#include <descrip.h>
#include <prcdef.h>
#include <jpidef.h>
#include <ssdef.h>
#include "bboard.h"

int setuname_used;			/* Do we need to clean up afterwards? */

static FILE * com_file; 		/* Maintain info about the stream */
static char com_fn[200];
#ifdef DEBUG
static char log_fn[200];
#endif

int post_job_running(void);

/* Run a detached process to write out unwritten notes */

void com_write_notes(void)
{
    static struct dsc$descriptor cmd_d;
    static struct dsc$descriptor inp_d;
    static struct dsc$descriptor out_d;
    static struct dsc$descriptor nam_d;
    char prcnam[16];
    static unsigned long prc_cnt = 1;

    /* Are we allowed to write Notes or do we need to wait until later? */

    if (postings_suspended && !shutdown_state) {
	timer_reset();
	return;
    }

    /* Let's make sure that there aren't any posting jobs running */

    if (post_job_running()) {
	timer_reset();			/* Let's set up to do it again */
	return;
    }

    /* Need to write close-up commands */

    com_file = fopen(com_fn, "a+");

    if (setuname_used) {
	fputs("$ setuname 'oldname'\n", com_file);
    }
#ifndef DEBUG
    fprintf(com_file, "$ delete %s;*\n", com_fn);
#endif
    fputs("$ exit\n", com_file);
    fclose(com_file);

    /* Magic here to run detached process 'com_fn' */

    str_desc(&cmd_d, "SYS$SYSTEM:LOGINOUT.EXE");
    str_desc(&inp_d, com_fn);
#ifdef DEBUG
    str_desc(&out_d, log_fn);
#else
    str_desc(&out_d, "NL:");
#endif
    sprintf(prcnam, "BB_Post_%07lX", prc_cnt++);
    prc_cnt &= 0xfffffff;
    str_desc(&nam_d, prcnam);

    /* Run with it */

    status = sys$creprc(NULL, &cmd_d, &inp_d, &out_d, NULL, 0, NULL, &nam_d,
	    2L, 0L, 0, PRC$M_DETACH | PRC$M_NOUAF);

    if (status != SS$_NORMAL) {
	report_error("Sys$Creprc failed", status);
    }

    /* And reset everything to "nothing to write out" */

    timer_reset();			/* Kick the timer */

    new_count = 0;			/* Nothing unwritten */
}

/* Open the .COM file for writing new stuff */

FILE * com_open(void)
{
    SYSTIM cur_time;
    struct $NUMTIM t;

    /* Are we opening this for the first time? */

    if (!new_count) {

	/* Get time information to build the file name */

	get_time(cur_time);
	get_numtim(&t, cur_time);

	/* So, now build the file name */

	sprintf(com_fn, "%sNOTERUN-%04d-%04d%04d.COM",
		scratch_dir.dsc$a_pointer, t.month * 100 + t.day,
		t.hour * 100 + t.minute, t.second * 100 + t.h_second);

#ifdef DEBUG
	strcpy(log_fn, com_fn);

	log_fn[strlen(log_fn)-4] = '\0';
	strcat(log_fn, ".LOG");
#endif

	/* Open it for initial commands */

	com_file = fopen(com_fn, "w", "ctx=rec", "rat=cr", "rfm=var");
	fputs("$ define notes$command nl:\n", com_file);
	fprintf(com_file, "$ define notes$notebook %snotes$notebook.note\n",
		root_dir.dsc$a_pointer);
	fprintf(com_file, "$ define sys$scratch bboard_scratch_dir\n");
	fprintf(com_file, "$ setuname :== $%sSETUNAME.EXE\n",
		root_dir.dsc$a_pointer);
	fputs("$ oldname == f$getjpi(\"\",\"USERNAME\")\n", com_file);

	/* Haven't used SETUNAME yet */

	setuname_used = FALSE;

    } else {

	/* Just open the file, otherwise */

	com_file = fopen(com_fn, "a+");

    }
    return(com_file);
}

/* Close the .COM file and update the un-written note count */

void com_close(int upd_count)
{
    /* Close the file first off */

    fclose(com_file);

    /* Update the un-written note count */

    if (upd_count < 0) {
	new_count = upd_count;
    } else if (upd_count > 0) {
	if (new_count >= 0) {
	    new_count += upd_count;
	}
    }
}

/* Check if there's another posting job running */

int post_job_running(void)
{
    long context;			/* What PID are we talking about */
    static char prcnam[16];		/* Place to stuff the process name */
    static long job_type;		/* What job type? */
    static struct itm_lst {
	short buf_len;
	short item_code;
	void * buffer;
	long * ret_len_addr;
    } item_list[3] = {
	{ 15, JPI$_PRCNAM, prcnam, 0},
	{ sizeof(job_type), JPI$_JOBTYPE, &job_type, 0},
	{ 0, 0}
    };

    context = -1L;

    while (TRUE) {			/* Search through all of them */
	status = sys$getjpiw(0, &context, 0, item_list, 0, 0, 0);
	if (status == SS$_NOPRIV || status == SS$_SUSPENDED) {
	    continue;
	}
	if (status == SS$_NOMOREPROC || !(status & 1)) {
	    break;
	}
	if (job_type) 			continue;
	if (strncmp(prcnam, "BB_Post_", 8))	continue;
	return (TRUE);
    }
    return (FALSE);
}
