/*++
/* NAME
/* showq_json 8
/* SUMMARY
/* JSON queue status formatter
/* SYNOPSIS
/* void showq_json(
/* VSTREAM *showq)
/* DESCRIPTION
/* This function converts showq(8) daemon output to JSON format.
/* DIAGNOSTICS
/* Fatal errors: out of memory, malformed showq(8) daemon output.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/
/* System library. */
#include <sys_defs.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sysexits.h>
#include <ctype.h>
#include <errno.h>
/* Utility library. */
#include <vstring.h>
#include <vstream.h>
#include <stringops.h>
#include <mymalloc.h>
#include <msg.h>
/* Global library. */
#include <mail_proto.h>
#include <mail_queue.h>
#include <mail_date.h>
#include <mail_params.h>
/* Application-specific. */
#include <postqueue.h>
#define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(x)
/* json_message - report status for one message */
static void format_json(VSTREAM *showq_stream)
{
static VSTRING *queue_name = 0 ;
static VSTRING *queue_id = 0 ;
static VSTRING *oaddr = 0 ;
static VSTRING *addr = 0 ;
static VSTRING *log_class = 0 ;
static VSTRING *why = 0 ;
static VSTRING *quote_buf = 0 ;
long arrival_time;
long message_size;
int showq_status;
int rcpt_count = 0 ;
int forced_expire;
/*
* One - time initialization .
*/
if (queue_name == 0 ) {
queue_name = vstring_alloc(100 );
queue_id = vstring_alloc(100 );
oaddr = vstring_alloc(100 );
addr = vstring_alloc(100 );
log_class = vstring_alloc(100 );
why = vstring_alloc(100 );
quote_buf = vstring_alloc(100 );
}
/*
* Force JSON values to UTF - 8 ( with SMTPUTF8 enabled ) or ASCII ( with
* SMTPUTF8 disabled ) .
*/
#define QUOTE_JSON(res, src) printable(quote_for_json((res), (src), -1 ), '?' )
/*
* Read the message properties and sender address .
*/
if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT
| ATTR_FLAG_PRINTABLE,
RECV_ATTR_STR(MAIL_ATTR_QUEUE, queue_name),
RECV_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
RECV_ATTR_LONG(MAIL_ATTR_TIME, &arrival_time),
RECV_ATTR_LONG(MAIL_ATTR_SIZE, &message_size),
RECV_ATTR_INT(MAIL_ATTR_FORCED_EXPIRE, &forced_expire),
RECV_ATTR_STR(MAIL_ATTR_SENDER, addr),
ATTR_TYPE_END) != 6 )
msg_fatal_status(EX_SOFTWARE, "malformed showq server response" );
vstream_printf("{" );
vstream_printf("\" queue_name\": \" %s\", " ,
QUOTE_JSON(quote_buf, STR(queue_name)));
vstream_printf("\" queue_id\": \" %s\", " ,
QUOTE_JSON(quote_buf, STR(queue_id)));
vstream_printf("\" arrival_time\": %ld, " , arrival_time);
vstream_printf("\" message_size\": %ld, " , message_size);
vstream_printf("\" forced_expire\": %s, " , forced_expire ? "true" : "false" );
vstream_printf("\" sender\": \" %s\", " ,
QUOTE_JSON(quote_buf, STR(addr)));
/*
* Read zero or more ( recipient , reason ) pair ( s ) until attr_scan_more ( )
* consumes a terminator . If the showq daemon messes up , don ' t try to
* resynchronize .
*/
vstream_printf("\" recipients\": [" );
for (rcpt_count = 0 ; (showq_status = attr_scan_more(showq_stream)) > 0 ; rcpt_count++) {
if (rcpt_count > 0 )
vstream_printf(", " );
vstream_printf("{" );
if (attr_scan(showq_stream, ATTR_FLAG_MORE | ATTR_FLAG_STRICT
| ATTR_FLAG_PRINTABLE,
RECV_ATTR_STR(MAIL_ATTR_ORCPT, oaddr),
RECV_ATTR_STR(MAIL_ATTR_RECIP, addr),
RECV_ATTR_STR(MAIL_ATTR_LOG_CLASS, log_class),
RECV_ATTR_STR(MAIL_ATTR_WHY, why),
ATTR_TYPE_END) != 4 )
msg_fatal_status(EX_SOFTWARE, "malformed showq server response" );
vstream_printf("\" orig_address\": \" %s\", " ,
QUOTE_JSON(quote_buf, STR(oaddr)));
vstream_printf("\" address\": \" %s\"" ,
QUOTE_JSON(quote_buf, STR(addr)));
if (LEN(why) > 0 )
vstream_printf(", \" %s\": \" %s\"" ,
strcmp(STR(log_class), MAIL_QUEUE_DEFER) == 0 ? "delay_reason" :
strcmp(STR(log_class), MAIL_QUEUE_BOUNCE) == 0 ? "bounce_reason" :
"other_reason" ,
QUOTE_JSON(quote_buf, STR(why)));
vstream_printf("}" );
}
vstream_printf("]" );
if (showq_status < 0 )
msg_fatal_status(EX_SOFTWARE, "malformed showq server response" );
vstream_printf("}\n" );
if (vstream_fflush(VSTREAM_OUT) && errno != EPIPE)
msg_fatal_status(EX_IOERR, "output write error: %m" );
}
/* showq_json - streaming JSON-format output adapter */
void showq_json(VSTREAM *showq_stream)
{
int showq_status;
/*
* Emit zero or more queue file objects until attr_scan_more ( ) consumes a
* terminator .
*/
while ((showq_status = attr_scan_more(showq_stream)) > 0
&& vstream_ferror(VSTREAM_OUT) == 0 ) {
format_json(showq_stream);
}
if (showq_status < 0 )
msg_fatal_status(EX_SOFTWARE, "malformed showq server response" );
}
Messung V0.5 in Prozent C=93 H=99 G=95
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-08-08)
¤
*© Formatika GbR, Deutschland