Fix debug output so built up output lines are readable again.

A recent change to Asterisk put the span number at the begining of each
line.  This is a good thing if you need to debug multiple spans or forget
which span you are debugging.  Unfortunately, any pri_message() output
that is not a complete line is messed up.

The pri_message() function now will accumulate line output until a '\n' is
seen on the end.


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1351 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Richard Mudgett 2009-11-21 02:40:23 +00:00
parent b9397c7541
commit 46df6d2cd4
2 changed files with 86 additions and 10 deletions

80
pri.c
View File

@ -239,6 +239,7 @@ void __pri_free_tei(struct pri * p)
pri_schedule_del(call->pri, call->retranstimer); pri_schedule_del(call->pri, call->retranstimer);
pri_call_apdu_queue_cleanup(call); pri_call_apdu_queue_cleanup(call);
} }
free(p->msg_line);
free(p); free(p);
} }
} }
@ -267,6 +268,14 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
p = &dummy_ctrl->ctrl; p = &dummy_ctrl->ctrl;
break; break;
} }
if (!master) {
/* This is the master record. */
p->msg_line = calloc(1, sizeof(*p->msg_line));
if (!p->msg_line) {
free(p);
return NULL;
}
}
p->bri = bri; p->bri = bri;
p->fd = fd; p->fd = fd;
@ -1121,20 +1130,77 @@ void pri_set_error(void (*func)(struct pri *pri, char *stuff))
__pri_error = func; __pri_error = func;
} }
void pri_message(struct pri *pri, char *fmt, ...) static void pri_old_message(struct pri *ctrl, const char *fmt, va_list *ap)
{ {
char tmp[1024]; char tmp[1024];
va_list ap;
va_start(ap, fmt); vsnprintf(tmp, sizeof(tmp), fmt, *ap);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
if (__pri_message) if (__pri_message)
__pri_message(PRI_MASTER(pri), tmp); __pri_message(ctrl, tmp);
else else
fputs(tmp, stdout); fputs(tmp, stdout);
} }
void pri_error(struct pri *pri, char *fmt, ...) void pri_message(struct pri *ctrl, const char *fmt, ...)
{
int added_length;
va_list ap;
ctrl = PRI_MASTER(ctrl);
if (!ctrl || !ctrl->msg_line) {
/* Just have to do it the old way. */
va_start(ap, fmt);
pri_old_message(ctrl, fmt, &ap);
va_end(ap);
return;
}
va_start(ap, fmt);
added_length = vsnprintf(ctrl->msg_line->str + ctrl->msg_line->length,
sizeof(ctrl->msg_line->str) - ctrl->msg_line->length, fmt, ap);
va_end(ap);
if (added_length < 0
|| sizeof(ctrl->msg_line->str) <= ctrl->msg_line->length + added_length) {
static char truncated_output[] =
"v-- Error building output or output was truncated. (Next line) --v\n";
/*
* This clause should never need to run because the
* output line accumulation buffer is quite large.
*/
/* vsnprintf() error or output string was truncated. */
if (__pri_message) {
__pri_message(ctrl, truncated_output);
} else {
fputs(truncated_output, stdout);
}
/* Add a terminating '\n' to force a flush of the line. */
ctrl->msg_line->length = strlen(ctrl->msg_line->str);
if (ctrl->msg_line->length) {
ctrl->msg_line->str[ctrl->msg_line->length - 1] = '\n';
} else {
ctrl->msg_line->str[0] = '\n';
ctrl->msg_line->str[1] = '\0';
}
} else {
ctrl->msg_line->length += added_length;
}
if (ctrl->msg_line->length
&& ctrl->msg_line->str[ctrl->msg_line->length - 1] == '\n') {
/* The accumulated output line was terminated so send it out. */
ctrl->msg_line->length = 0;
if (__pri_message) {
__pri_message(ctrl, ctrl->msg_line->str);
} else {
fputs(ctrl->msg_line->str, stdout);
}
}
}
void pri_error(struct pri *pri, const char *fmt, ...)
{ {
char tmp[1024]; char tmp[1024];
va_list ap; va_list ap;

View File

@ -55,12 +55,22 @@ struct pri_sched {
/*! Maximum number of facility ie's to handle per incoming message. */ /*! Maximum number of facility ie's to handle per incoming message. */
#define MAX_FACILITY_IES 8 #define MAX_FACILITY_IES 8
/*! Accumulated pri_message() line until a '\n' is seen on the end. */
struct pri_msg_line {
/*! Accumulated buffer used. */
unsigned length;
/*! Accumulated pri_message() contents. */
char str[2048];
};
/*! \brief D channel controller structure */ /*! \brief D channel controller structure */
struct pri { struct pri {
int fd; /* File descriptor for D-Channel */ int fd; /* File descriptor for D-Channel */
pri_io_cb read_func; /* Read data callback */ pri_io_cb read_func; /* Read data callback */
pri_io_cb write_func; /* Write data callback */ pri_io_cb write_func; /* Write data callback */
void *userdata; void *userdata;
/*! Accumulated pri_message() line. (Valid in master record only) */
struct pri_msg_line *msg_line;
struct pri *subchannel; /* Sub-channel if appropriate */ struct pri *subchannel; /* Sub-channel if appropriate */
struct pri *master; /* Master channel if appropriate */ struct pri *master; /* Master channel if appropriate */
struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */ struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */
@ -525,7 +535,7 @@ struct q931_call {
/*! D channel control structure with associated dummy call reference record. */ /*! D channel control structure with associated dummy call reference record. */
struct d_ctrl_dummy { struct d_ctrl_dummy {
/*! D channel control structure. */ /*! D channel control structure. Must be first in the structure. */
struct pri ctrl; struct pri ctrl;
/*! Dummy call reference call record. */ /*! Dummy call reference call record. */
struct q931_call dummy_call; struct q931_call dummy_call;
@ -539,8 +549,8 @@ extern void pri_schedule_del(struct pri *pri, int ev);
extern pri_event *pri_mkerror(struct pri *pri, char *errstr); extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
void pri_message(struct pri *ctrl, char *fmt, ...) __attribute__((format(printf, 2, 3))); void pri_message(struct pri *ctrl, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void pri_error(struct pri *ctrl, char *fmt, ...) __attribute__((format(printf, 2, 3))); void pri_error(struct pri *ctrl, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void libpri_copy_string(char *dst, const char *src, size_t size); void libpri_copy_string(char *dst, const char *src, size_t size);