static int stomp_msg_input(sf_t *sf, char *buf, int len, void *udata) { int state; stomp_msg_t msg; stomp_command_tables_t *t; if (udata == NULL) { plog(LOG_ERR, "%s: udata == NULL. why?", __func__); return -1; } state = stomp_get_state(sf); t = &StompCommands[state]; plog(LOG_DEBUG, "%s: [input] state = %d, buf = >>>\n%s<<<", __func__, state, buf); if (stomp_parse(&msg, buf, len, t->sct_cmds, t->sct_num) < 0) { plog(LOG_ERR, "%s: stomp_parse() failed", __func__); return -1; } if (msg.sm_cmd->sc_func(sf, udata, &msg) < 0) return -1; stomp_set_state(sf, msg.sm_cmd->sc_next_state); return 0; }
static int stomp_msg_estimlen(sf_t *sf, char *buf, int len, void *udata) { int est_len; char *p, clen[256]; stomp_msg_t msg; if (stomp_parse(&msg, buf, len, NULL, 0) < 0) { plog(LOG_DEBUG, "%s: stomp_parse() failed", __func__); return -1; } if (stomp_read_header(clen, sizeof(clen), &msg, "content-length:") < 0) return -1; est_len = strtol(clen, &p, 10); if (*p != '\n' && *p != '\r' && *p != 0) return -1; if (msg.sm_body == NULL || msg.sm_buf == NULL) return -1; /* message body size + header size + terminator size */ est_len += (msg.sm_body - msg.sm_buf) + 1; plog(LOG_DEBUG, "%s: estimated message length = %d", __func__, est_len); return est_len; }
/* * Setup the connection to the stomp server, and handle initial protocol * negotiations (sending user/passcode over to the server in particular). * Stomp protocol is clear text... (we don't need no stinkin' security!). * Note: this routine is used for both the initial connection and also for * any subsequent reconnect attempts. */ void stompInit(void) { time_t thistime; static time_t lasttime; static int firsttime = 1; if (firsttime) { /* initial connection attempt */ stomp_parse(); if (!topic) topic = pmietopic; atexit(stomp_disconnect); } else { /* reconnect attempt, if not too soon */ time(&thistime); if (thistime < lasttime + 60) goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Connecting to %s, port %d", hostname, port); if (stomp_connect(hostname, port) < 0) { __pmNotifyErr(LOG_ERR, "Could not connect to the message server"); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Connected; sending stomp connect message"); if (stomp_authenticate() < 0) { __pmNotifyErr(LOG_ERR, "Could not sent STOMP CONNECT frame to server"); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Sent; waiting for server ACK"); if (stomp_read_ack() < 0) { __pmNotifyErr(LOG_ERR, "Could not read STOMP ACK frame."); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "ACK; sending initial PMIE topic and hello"); if (stomp_destination() < 0) { __pmNotifyErr(LOG_ERR, "Could not read TOPIC frame."); goto disconnect; } if (stomp_hello() < 0) { __pmNotifyErr(LOG_ERR, "Could not send HELLO frame."); goto disconnect; } if (verbose) __pmNotifyErr(LOG_INFO, "Sent; waiting for server ACK"); if (stomp_read_ack() < 0) { __pmNotifyErr(LOG_ERR, "Could not read STOMP ACK frame"); goto disconnect; } if (!firsttime) __pmNotifyErr(LOG_INFO, "Reconnected to STOMP protocol server"); else if (verbose) __pmNotifyErr(LOG_INFO, "Initial STOMP protocol setup complete"); firsttime = 0; goto finished; disconnect: stomp_disconnect(); if (firsttime) exit(1); /* otherwise, we attempt reconnect on next message firing (>1min) */ finished: lasttime = thistime; }