/* $Id: srtupdate.c,v 1.7 2008/12/05 15:58:05 ksb Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include "machine.h" #if !defined(DEF_RRDD_PORT) #define DEF_RRDD_PORT 31415 #endif extern char *progname; /* update the file.srt on the PEG host with a new string (ksb) * Like rrrdupdate we'll remember peg's info * pePeg [host][:port] (last used, or localhost:31415) * pcFile [path/file.srt] (-) * pcName no default, name in table * pcData [strings] (-) * ptNow [& time] (N) * pass a (char *)0 for pcName to close the socket we hold open, or * to open a new one. */ int srtupdate(char *pcPeg, char *pcFile, char *pcName, char *pcData, time_t *ptNow) { static int s = -1; static struct sockaddr_in sind; static int iPort; register struct hostent *hp; register int iError; register char *pcTemp; auto struct sockaddr_in sins; auto char acSend[8192]; /* UDP max datagram is ~8k -- ksb*/ auto char acHost[MAXHOSTNAMELEN+4]; auto char acStamp[64]; /* a time in seconds since the epoch */ static char acDash[] = "-"; if ((char *)0 != pcPeg) { if (-1 != s) { (void)shutdown(s, SHUT_RDWR); (void)close(s); } s = -1; /* look for ":port" or "host:port", else assume just "host" */ iPort = DEF_RRDD_PORT; if ((char *)0 != (pcTemp = strchr(pcPeg, ':'))) { if (pcTemp-pcPeg > sizeof(acHost)) { return -__LINE__; } (void)strncpy(acHost, pcPeg, (size_t)(pcTemp-pcPeg)); if ('\000' != pcTemp[1]) { iPort = strtoul(pcTemp+1, (char **)0, 10); } } else { /* just a host */ (void)strncpy(acHost, pcPeg, sizeof(acHost)); } (void)memset(&sind, 0, sizeof sind); if ('\000' == acHost[0]) { (void)strcpy(acHost, "localhost"); sins.sin_addr.s_addr = INADDR_LOOPBACK; } else if ((struct hostent *)0 == (hp = gethostbyname(acHost))) { fprintf(stderr, "%s: gethostbyname: %s: %s\n", progname, acHost, strerror(errno)); return -__LINE__; } else { (void)memcpy(&(sind.sin_addr.s_addr), hp->h_addr, hp->h_length); } sind.sin_family = AF_INET; sind.sin_port = htons(iPort); if (s < (s = socket(AF_INET, SOCK_DGRAM, 0))) { return -__LINE__; } (void)memset(&sins, 0, sizeof sins); sins.sin_family = AF_INET; iError = bind(s, (struct sockaddr *)&sins, sizeof(sins)); if (iError < 0) { close(s); return -__LINE__; } if ((char *)0 == pcName) { return 0; } } if ((char *)0 == pcName) { if (-1 != s) { (void)shutdown(s, SHUT_RDWR); (void)close(s); } s = -1; return 0; } if (-1 == s) { return -__LINE__; } if ((char *)0 == pcFile || '\000' == *pcFile) { pcFile = acDash; } if ((char *)0 == pcData || '\000' == *pcData) { pcData = acDash; } /* Check for too much data to fit in packet * datagram - lenght("10 " + " " + " " + " " + "$secons:" + '\000') */ if (strlen(pcFile)+strlen(pcName)+strlen(pcData) > sizeof(acSend)-(3+1+1+1+12+1)) { return E2BIG; } if ((time_t *)0 == ptNow) { (void)strcpy(acStamp, "N"); } else { sprintf(acStamp, "%ld", (unsigned long)*ptNow); } for (pcTemp = pcFile; *pcTemp; ++pcTemp) { if (!isgraph(*pcTemp)) return -__LINE__; } /* build the update, and send it out */ #if HAVE_NPRINTF snprintf(acSend, sizeof(acSend), "10 %s %s %s:%s", pcFile, pcName, acStamp, pcData); #else sprintf(acSend, "10 %s %s %s:%s", pcFile, pcName, acStamp, pcData); #endif iError = sendto(s, acSend, strlen(acSend), 0, (struct sockaddr *)&sind, sizeof(sind)); return iError; }