static void HailExec(AgentConnection *conn, char *peer, char *recvbuffer, char *sendbuffer) { if (DEFINECLASSES[0] != '\0') { snprintf(sendbuffer, CF_BUFSIZE, "EXEC -D%s", DEFINECLASSES); } else { snprintf(sendbuffer, CF_BUFSIZE, "EXEC"); } if (SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Transmission rejected. (send: %s)", GetErrorStr()); DisconnectServer(conn); return; } /* TODO we are sending class data right after EXEC, when the server might * have already rejected us with BAD reply. So this class data with the * CFD_TERMINATOR will be interpreted by the server as a new, bogus * protocol command, and the server will complain. */ SendClassData(conn); FILE *fp = NewStream(peer); while (true) { memset(recvbuffer, 0, CF_BUFSIZE); int n_read = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (n_read == -1) { break; } if (n_read == 0) /* connection closed */ { break; } if (strncmp(recvbuffer, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { break; } const size_t recv_len = strlen(recvbuffer); const char *ipaddr = conn->remoteip; if (strncmp(recvbuffer, "BAD:", 4) == 0) { fprintf(fp, "%s> !! %s\n", ipaddr, recvbuffer + 4); } /* cf-serverd >= 3.7 quotes command output with "> ". */ else if (strncmp(recvbuffer, "> ", 2) == 0) { fprintf(fp, "%s> -> %s", ipaddr, &recvbuffer[2]); } else { fprintf(fp, "%s> %s", ipaddr, recvbuffer); } if (recv_len > 0 && recvbuffer[recv_len - 1] != '\n') { /* We'll be printing double newlines here with new cf-serverd * versions, so check for already trailing newlines. */ /* TODO deprecate this path in a couple of versions. cf-serverd is * supposed to munch the newlines so we must always append one. */ fputc('\n', fp); } } if (fp != stdout) { fclose(fp); } DisconnectServer(conn); }
static void HailExec(AgentConnection *conn, char *peer, char *recvbuffer, char *sendbuffer) { FILE *fp = stdout; char *sp; int n_read; if (strlen(DEFINECLASSES)) { snprintf(sendbuffer, CF_BUFSIZE, "EXEC %s -D%s", REMOTE_AGENT_OPTIONS, DEFINECLASSES); } else { snprintf(sendbuffer, CF_BUFSIZE, "EXEC %s", REMOTE_AGENT_OPTIONS); } if (SendTransaction(conn->sd, sendbuffer, 0, CF_DONE) == -1) { CfOut(cf_error, "send", "Transmission rejected"); DisconnectServer(conn); return; } fp = NewStream(peer); SendClassData(conn); while (true) { memset(recvbuffer, 0, CF_BUFSIZE); if ((n_read = ReceiveTransaction(conn->sd, recvbuffer, NULL)) == -1) { return; } if (n_read == 0) { break; } if (strlen(recvbuffer) == 0) { continue; } if ((sp = strstr(recvbuffer, CFD_TERMINATOR)) != NULL) { fprintf(fp, "%s> !!\n\n", VPREFIX); break; } if ((sp = strstr(recvbuffer, "BAD:")) != NULL) { fprintf(fp, "%s> !! %s\n", VPREFIX, recvbuffer + 4); continue; } if (strstr(recvbuffer, "too soon")) { fprintf(fp, "%s> !! %s\n", VPREFIX, recvbuffer); continue; } fprintf(fp, "%s> -> %s", VPREFIX, recvbuffer); } DeleteStream(fp); DisconnectServer(conn); }
static void HailExec(AgentConnection *conn, char *peer) { char sendbuf[CF_BUFSIZE - CF_INBAND_OFFSET] = "EXEC"; size_t sendbuf_len = strlen(sendbuf); if (!NULL_OR_EMPTY(DEFINECLASSES)) { StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, " -D", 0); StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, DEFINECLASSES, 0); } if (!NULL_OR_EMPTY(REMOTEBUNDLES)) { StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, " -b ", 0); StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, REMOTEBUNDLES, 0); } if (sendbuf_len >= sizeof(sendbuf)) { Log(LOG_LEVEL_ERR, "Command longer than maximum transaction packet"); DisconnectServer(conn); return; } if (SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Transmission rejected. (send: %s)", GetErrorStr()); DisconnectServer(conn); return; } /* TODO we are sending class data right after EXEC, when the server might * have already rejected us with BAD reply. So this class data with the * CFD_TERMINATOR will be interpreted by the server as a new, bogus * protocol command, and the server will complain. */ SendClassData(conn); char recvbuffer[CF_BUFSIZE]; FILE *fp = NewStream(peer); while (true) { memset(recvbuffer, 0, sizeof(recvbuffer)); if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { break; } if (strncmp(recvbuffer, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { break; } const size_t recv_len = strlen(recvbuffer); const char *ipaddr = conn->remoteip; if (strncmp(recvbuffer, "BAD:", 4) == 0) { fprintf(fp, "%s> !! %s\n", ipaddr, recvbuffer + 4); } /* cf-serverd >= 3.7 quotes command output with "> ". */ else if (strncmp(recvbuffer, "> ", 2) == 0) { fprintf(fp, "%s> -> %s", ipaddr, &recvbuffer[2]); } else { fprintf(fp, "%s> %s", ipaddr, recvbuffer); } if (recv_len > 0 && recvbuffer[recv_len - 1] != '\n') { /* We'll be printing double newlines here with new cf-serverd * versions, so check for already trailing newlines. */ /* TODO deprecate this path in a couple of versions. cf-serverd is * supposed to munch the newlines so we must always append one. */ fputc('\n', fp); } } if (fp != stdout) { fclose(fp); } DisconnectServer(conn); }