/*
 *	Name:				xtool.c
 *
 * Description:	Tool for manipulating xferq.library
 *
 * Copyright:		1992 by David Jones.
 *
 * Distribution:
 *		This program is free software; you can redistribute it and/or modify
 *		it under the terms of the GNU General Public License as published by
 *		the Free Software Foundation; either version 2 of the License, or
 *		(at your option) any later version.
 *
 *		This program is distributed in the hope that it will be useful,
 *		but WITHOUT ANY WARRANTY; without even the implied warranty of
 *		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *		GNU General Public License for more details.
 *
 *		You should have received a copy of the GNU General Public License
 *		along with this program; if not, write to:
 *
 *				The Free Software Foundation		David Jones
 *				675 Mass Ave							6730 Tooney Drive
 *				Cambridge, MA							Orleans, Ontario
 *				02139										K1C 6R4
 *				USA										Canada
 *
 *	Usenet:	gnu@prep.ai.mit.edu					dej@qpoint.ocunix.on.ca
 *	Fidonet:												1:163/109.8
 *
 *		$Log:	xtool.c,v $
 * Revision 1.1  93/01/23  16:08:45  rwm
 * Initial revision
 * 
 *
 */

#include <exec/types.h>
#include <exec/execbase.h>
#include "xferq.h"
#include "xferq_pragmas.h"
#include <stdio.h>
#include <proto/exec.h>
#include <utility/hooks.h>
#include <stdlib.h>
#include <string.h>

struct Library *XferqBase;

char Command[80];

ULONG __asm SHWCB(register __a0 struct Hook *hook,
	register __a2 struct NetAddress *na, register __a1 struct TagItem *tags)
{
	char *astring;
	long pri;

	astring = XfqPutAddressTags(na,
		XQ_Mandatory, XQADDR_ANYTHING,
		XQ_Optional, XQADDR_ANYTHING,
		TAG_DONE);
	pri=XfqMaxSitePri(na);
        if(astring) {
		printf("%-30s %ld\n", astring,pri);
		XfqDropObject(astring);
	} else	printf("*** ERROR ***\n");
	return TRUE;
}


void SitesHavingWork(void)
{
struct Session *sites;
struct Hook hook;

	sites = XfqGetSiteList();
	printf("Sites having work            priority\n");
	printf("-----------------            --------\n\n");
	hook.h_Entry = SHWCB;
	
	XfqWalkSessionCallBackTags(sites,
		XQ_CallBack, &hook,
		TAG_DONE);
	printf("\n");
	XfqDropObject(sites);
}


struct NetAddress *GetAddress(char *buffer)
{
struct NetAddress *na;

	na = XfqGetAddressTags(buffer, NULL,
		XQ_Mandatory, XQADDR_3D,
		XQ_Optional, XQADDR_ANYTHING,
		TAG_DONE);
	if (!na) {
		printf("\nIllegal address.\n");
	}
	return na;
}


void AddNode(void)
{
char site[20], name[40], asname[15], flags[4];
int pri, numargs, flagb;
char *asnamep, *flagp;
char *errmsg;

	numargs = sscanf(Command, "%*c %s %s %d %s %s",
		site, name, &pri, flags, asname);
	if (numargs < 4 || numargs > 5) {
		printf("Usage: a site name pri flags(DTIL) [asname]\n");
		return;
	}
	asnamep = (numargs == 4) ? NULL : asname;
	flagb = 0;
	flagp = flags;
	while (*flagp) {
		switch (*flagp) {
		case 'D':
		case 'd':
			flagb |= XQ_DELETE;
			break;
		case 'T':
		case 't':
			flagb |= XQ_TRUNCATE;
			break;
		case 'I':
		case 'i':
			flagb |= XQ_IMMEDIATE;
			break;
		case 'L':
		case 'l':
			flagb |= XQ_SENDLATER;
			break;
		}
		flagp++;
	}
	if (!XfqAddWorkQuick(site, name, asnamep, pri, flagb)) {
		errmsg = XfqErrorMsg(XfqGetError());
		printf("\nFailed due to %s.\n", errmsg);
		XfqDropObject(errmsg);
	} else
		printf("Work Added\n");
}


ULONG __asm ListQCB(register __a0 struct Hook *hook,
	register __a2 struct WorkNode *wn,
	register __a1 struct TagItem *tags)
{
char *name, *asname;
int pri, flags, status;

	XfqExamObjectTags(wn,
		XQ_Name, &name,
		XQ_AsName, &asname,
		XQ_Pri, &pri,
		XQ_Flags, &flags,
		XQ_Status, &status,
		TAG_DONE);
	printf("%08x  ", wn);
	if (name) {
		printf("%-30s  ", name);
		XfqDropObject(name);
	} else printf("%-30s  ", "");
	if (asname) {
		printf("%-14s  ", asname);
		XfqDropObject(asname);
	}else printf("%-14s  ", "");
	printf("%4d  ", pri);
	putc(flags & XQ_SENDLATER ? 'L' : '-', stdout);
	putc(flags & XQ_IMMEDIATE ? 'I' : '-', stdout);
	putc(flags & XQ_TRUNCATE ? 'T' : '-', stdout);
	putc(flags & XQ_DELETE ? 'D' : '-', stdout);
	printf("  %2d\n", status);
	return TRUE;
}


void ListQueue(void)
{
struct Hook hook;
struct NetAddress *na;
char astring[40];

	hook.h_Entry = ListQCB;
	sscanf(Command, "%*c %s", astring);
	na = GetAddress(astring);
	if (na) {
		printf("\nNode      Name                            "
			"Asname          Pri   Flags Status");
		printf("\n--------  ------------------------------  "
			"--------------  ----  ----- -----\n");
		XfqWalkQueueCallBackTags(na,
			XQ_CallBack, &hook,
			TAG_DONE);
		XfqDropObject(na);
	}
}

void CheckWork(void)
{
struct Hook hook;
struct NetAddress *na;
char astring[40];

	hook.h_Entry = ListQCB;
	sscanf(Command, "%*c %s", astring);
	na = GetAddress(astring);
	if (na) {
	  struct WorkNode *work;

		printf("\nAny Work returns %ld\n",XfqAnyWorkTags(na,TAG_DONE));	
		work=XfqGetWorkTags(na,TAG_DONE);
		if (work) {
		  long temp;
                  struct WorkNode *newwork;

			printf("Work node %lx\n",work);
			XfqExamObjectTags(work,XQ_Flags,&temp,TAG_DONE);
			newwork=XfqModifyObjectTags(work,XQ_Flags,
				temp|XQ_SENDLATER,TAG_DONE);
			if(newwork) XfqUnlockWork(newwork);
			else XfqUnlockWork(work);
		}
		printf("\nAny Work returns %ld\n",XfqAnyWorkTags(na,TAG_DONE));	
		XfqDropObject(na);
	}
}

void HoldMailer(void)
{
struct NetAddress *na;
char astring[40];

	sscanf(Command, "%*c %s", astring);
	na = GetAddress(astring);
	if (na) { 
		printf("\nXfqHoldMailer returns %ld\n",XfqHoldMailer(na));	
		XfqDropObject(na);
	}
}

void ReleaseMailer(void)
{
struct NetAddress *na;
char astring[40];

	sscanf(Command, "%*c %s", astring);
	na = GetAddress(astring);
	if (na) { 
		printf("\nXfqHoldMailer returns %ld\n",XfqReleaseMailer(na));	
		XfqDropObject(na);
	}
}

void RemNode(void)
{
struct NetAddress *na;
struct WorkNode *wn;
char astring[40];
char name[80];
char *errmsg;

	if(sscanf(Command, "%*c %s %s", astring, name)!=2) {
		printf("Usage: r site name\n");
		return;
	}
	na = GetAddress(astring);
	if (na) {
		wn = XfqFindWorkTags(
			XQ_Site, na,
			XQ_Name, name,
			TAG_DONE);
		if (wn) {
			XfqRemoveWork(wn);
		}
		else {
			errmsg = XfqErrorMsg(XfqGetError());
			printf("Cannot - %s.\n", errmsg);
			XfqDropObject(errmsg);
		}
		XfqDropObject(na);
	}
}


int main(int argc, char *argv[])
{
int len;

	XferqBase = OpenLibrary("xferq.library", 1);
	if (!XferqBase) {
		printf("Need xferq.library V1 or better!\n");
		exit(10);
	}
	SitesHavingWork();
	do {
		printf("\nxtool> ");
		fflush(stdout);
		fgets(Command, sizeof(Command), stdin);
		len = strlen(Command);
		if (Command[len -1] == '\n') {
			Command[len - 1] = '\0';
		}
		switch (Command[0]) {
                case 'q':
                case 'Q':
			break;
		case 'a':	/* add */
			AddNode();
			break;
		case 'l':	/* list */
			ListQueue();
			break;
		case 's':	/* site list */
			SitesHavingWork();
			break;
		case 'r':	/* remove */
			RemNode();
			break;
		case 'f':	/* flush */
			XfqFlushQueue(NULL);
			printf("Queue Flushed to disk\n");
			break;
		case 'w':	/* work */
			CheckWork();
			break;
		case '1':	/* work */
			HoldMailer();
			break;
		case '2':	/* work */
			ReleaseMailer();
			break;
                default:
			printf("Command List\n\n");
			printf("a)dd\n");
			printf("f)lush\n");
			printf("l)list\n");
			printf("r)emove\n");
			printf("s)ite list\n");
			printf("q)uit\n");
			printf("w)ork check\n");
			printf("1) Hold Mailer\n");
			printf("2) release Mailer\n");
			break;
		}
	} while ((Command[0] != 'q') && (Command[0] != 'Q'));
	CloseLibrary(XferqBase);
	return 0;
}
