/*@Version $Revision: 1.3 $@*/ /*@Header@*/ /* $Id: rrrdupdate.mc,v 1.3 2008/12/05 16:22:55 ksb Exp $ */ %#if %K-1v || USE_STDARGS #include #else #include #endif /*@Explode update@*/ /* set up and use a socket to the rrdd on peg (ksb, others) * Pass in a Dest of (char *)0 to use the last one, if Fmt is (char *)0 * we just set the new Dest, or close the old one. * So: * rrrdupdate("new.host:27182", (char *)0, (char *)0, (char *)0); * just points us to the new.host's peg port, then: * rrrdupdate((char *)0, "host/myname/unix.rrd", "yada", "N:1.0"); * sends an update for my unix RRD. * * The definition below depend on our UDP max datagram begin ~8k --ksb */ %#if %K-1v || USE_STDARGS int rrrdupdate(char *pcDest, char *pcRrd, char *pcTemplate, char *pcFmt, ...) #else int rrrdupdate(pcDest, pcRrd, pcTemplate, pcFmt, va_alist) char *pcDest, *pcRrd, *pcTemplate, *pcFmt; va_dcl #endif { static int s = -1; static struct sockaddr_in sind; static char *pcPort, *pcHost; register struct hostent *hp; auto int error; auto struct sockaddr_in sins; auto char *pc; auto char buf1[8192], buf2[8192]; %#if %K-1v || USE_STDARGS va_list ap; #else va_list ap; #endif if ((char *)0 != pcDest && '\000' != pcDest) { if (-1 != s) { (void)shutdown(s, SHUT_RDWR); (void)close(s); s = -1; } pcDest = strdup(pcDest); (void)memset(&sind, 0, sizeof sind); sind.sin_family = AF_INET; pcPort = strchr(pcDest, ':'); if ((char *)0 != pcPort) { pcHost = pcDest; *pcPort++ = '\000'; } else { pcHost = (char *)0; pcPort = pcDest; } sind.sin_port = htons(strtoul(pcPort, &pc, 0)); if (*pcPort == '\000' || *pc != '\000') return -__LINE__; if ((char *)0 == pcHost) { sins.sin_addr.s_addr = INADDR_LOOPBACK; pcHost = "ANY"; } else { hp = gethostbyname(pcHost); if ((struct hostent *)0 == hp) { herror(pcHost); return -__LINE__; } memcpy(&(sind.sin_addr.s_addr), hp->h_addr, hp->h_length); } s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { return -__LINE__; } memset(&sins, 0, sizeof sins); sins.sin_family = AF_INET; error = bind(s, (struct sockaddr*)&sins, sizeof(sins)); if (error < 0) { close(s); s = -1; return -__LINE__; } if ((char *)0 == pcFmt) { return 0; } } if ((char *)0 == pcFmt) { if (-1 != s) { (void)shutdown(s, SHUT_RDWR); (void)close(s); } s = -1; return 0; } if (-1 == s) { return -__LINE__; } if ((char *)0 == pcRrd || '\000' == *pcRrd) pcRrd = "-"; for (pc = pcRrd; *pc; pc++) { if (!isgraph(*pc)) return -__LINE__; } if ((char *)0 == pcTemplate || '\000' == *pcTemplate) pcTemplate = "-"; for (pc = pcTemplate; *pc; pc++) { if (!isgraph(*pc)) return -__LINE__; } %#if %K-1v || USE_STDARGS va_start(ap, pcFmt); #else va_start(ap); #endif #if HAVE_NPRINTF error = vsnprintf(buf1, sizeof(buf1), pcFmt, ap); #else error = vsprintf(buf1, pcFmt, ap); #endif if (error == -1) { va_end(ap); return error; } for (pc = buf1; *pc; pc++) { if (!isgraph(*pc)) { va_end(ap); return -__LINE__; } } va_end(ap); #if HAVE_NPRINTF error = snprintf(buf2, sizeof(buf2), "00 %s %s %s", pcRrd, pcTemplate, buf1); #else error = sprintf(buf2, "00 %s %s %s", pcRrd, pcTemplate, buf1); #endif if (! fExec || fTrace) fprintf(stderr, "%s\n", buf2); if (fExec) error = sendto(s, buf2, strlen(buf2), 0, (struct sockaddr*)&sind, sizeof(sind)); return error; }