/*
 *	Copyright 1990 by Rayan S. Zachariassen, all rights reserved.
 *	This will be free software, but only when it is finished.
 */

/*
 * Common routine to produce a diagnostic message for the scheduler to read
 */

#include <stdio.h>
#include "hostenv.h"
#include <sysexits.h>
#ifdef STDARG_H
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <mail.h>
#include "ta.h"

void
#ifdef STDARG_H
diagnostic(struct rcpt *rp, ...)
#else
diagnostic(va_alist)
	va_dcl
#endif
{
	char	mark, message[8192];
	register char *cp, *s, *es, *s2;
	va_list	ap;
	extern int lockaddr();

#ifdef STDARG_H
	va_start(ap, rp);
#else
	struct rcpt *rp;
	va_start(ap);
	rp = va_arg(ap, struct rcpt *);
#endif
	rp->status = va_arg(ap, int);

	cp = va_arg(ap, char *);
	es = &message[sizeof message - 2];
	for (s = message; cp != NULL && *cp != '\0'; ++cp) {
		if (s >= es)
			break;
		if (*cp != '%') {
			*s++ = *cp;
			continue;
		}
		switch (*++cp) {
		case 's':	/* string */
			for (s2 = va_arg(ap, char *); *s2 != 0; ++s2) {
				*s++ = *s2;
				if (s >= es)
					break;
			}
			break;
		case 'd':	/* integer */
			if (s >= es - 10)
				break;
			(void) sprintf(s, "%d", va_arg(ap, int));
			while (*s != '\0') ++s;
			break;
		case '%':	/* percent */
			*s++ = '%';
			break;
		case '\0':
			--cp;	/* exit soonest */
			break;
		}
	}
	*s = '\0';
	va_end(ap);

	(void) printf("%d/%ld/", rp->desc->ctlid, rp->id);
	switch (rp->status) {
	case EX_OK:
		(void) printf("ok");
		mark = _CFTAG_OK;
		break;
	case EX_TEMPFAIL:
	case EX_IOERR:
	case EX_OSERR:
	case EX_CANTCREAT:
	case EX_SOFTWARE:
		(void) printf("deferred");
		mark = _CFTAG_DEFER;
		break;
	case EX_PROTOCOL:
	case EX_USAGE:
		(void) strncat(message,
			       " (this is abnormal, investigate!)", es - s);
		s += strlen(s);
		/* fall through */
	case EX_NOPERM:
	case EX_NOUSER:
	case EX_NOHOST:
	case EX_UNAVAILABLE:
		(void) printf("error");
		mark = _CFTAG_NOTOK;
		break;
	default:
		(void) printf("error Unknown sysexits error code %d!",
				     rp->status);
		mark = _CFTAG_NOTOK;
		break;
	}
	if (message[0] != '\0')
		(void) printf(" %s", message);
	(void) printf("\n");
	if (!lockaddr(rp->desc->ctlfd, rp->lockoffset, _CFTAG_LOCK, mark)) {
		/* something went wrong in unlocking it, concurrency problem? */
	}
	rp->lockoffset = 0;	/* mark this recipient unlocked */
	(void) fflush(stdout);
}
