#include #include #include #include #include #include #include #include #include #include #include #include const int BUFSIZE = 256; const long BAUD = B9600; const long DATABITS = CS8; const long STOPBITS = CSTOPB; static int help_flag; int fetch_temp(char *serial_port,double *temperature); void usage(int exit_code); int send_serial(int *fd,char *msg); int interpret_temp(char *msg,double temperature,int warning_low,int critical_low,int warning_high,int critical_high); int network(char *serial_port,int daemon_port); void fatal(char *string); int main (argc, argv) int argc; char **argv; { int c,warning_low,warning_high,critical_low, critical_high,daemon_port,rc; double temperature; char *serial_port,*msg; warning_low = warning_high = critical_low = critical_high = daemon_port = 0; while (1) { static struct option long_options[] = { {"help", no_argument, &help_flag, 1}, {"warning-low", required_argument, 0, 'a'}, {"warning-high", required_argument, 0, 'b'}, {"critical-low", required_argument, 0, 'c'}, {"critical-high", required_argument, 0, 'd'}, {"serial-port", required_argument, 0, 'e'}, {"daemon", required_argument, 0, 'f'}, {0, 0, 0, 0} }; int option_index = 0; c = getopt_long (argc, argv, "a:b:c:d:e:", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case 'a': warning_low = atoi(optarg); break; case 'b': warning_high = atoi(optarg); break; case 'c': critical_low = atoi(optarg); break; case 'd': critical_high = atoi(optarg); break; case 'e': serial_port = optarg; break; case 'f': daemon_port = atoi(optarg); break; case '?': break; default: abort (); } } if (help_flag) usage(0); if(!serial_port) usage(2); if(daemon_port > 0) { rc = network(serial_port,daemon_port); exit(rc); } if(!warning_low || !warning_high || !critical_low || !critical_high) usage(2); rc = fetch_temp(serial_port,&temperature); if(rc < 0) { fatal("fetch_temp failed"); } msg = malloc(BUFSIZE); rc = interpret_temp(msg,temperature,warning_low,critical_low,warning_high,critical_high); printf("%s\n", msg); return rc; } int interpret_temp(char *msg,double temperature,int warning_low,int critical_low,int warning_high,int critical_high) { int rc; if (temperature < critical_low) { sprintf(msg,"CRITICAL Temperature low: %f\n", temperature); rc = 2; } else if(temperature < warning_low) { sprintf(msg,"WARNING Temperature low: %f\n", temperature); rc = 1; } else if (temperature > critical_high) { sprintf(msg,"CRITICAL Temperature high: %f\n", temperature); rc = 2; } else if (temperature > warning_high) { sprintf(msg,"WARNING Temperature high: %f\n", temperature); rc = 1; } else { sprintf(msg,"OK Temperature: %f\n", temperature); rc = 0; } return rc; } int send_serial(int *fd,char *msg) { tcflush(*fd, TCIFLUSH); if( write(*fd,&msg,sizeof(msg)) != sizeof(msg)){ printf("Failed to write!\n"); return 0; } return 1; } int fetch_temp(char *serial_port,double *temperature) { struct termios oldtio, newtio; int rc,fd,i,regerroff,length; int ovector[BUFSIZE]; char *msg,*oldmsg,*pattern; const char *regerror; pcre *re; char buf[BUFSIZE]; fd = open(serial_port, O_RDWR | O_NONBLOCK | O_EXCL | O_NOCTTY); if(fd < 0) { return -1; } fcntl(fd, F_SETFL, 0); tcgetattr(fd,&oldtio); cfsetispeed(&newtio,BAUD); cfsetospeed(&newtio,BAUD); newtio.c_cflag = (CLOCAL | CREAD | BAUD | DATABITS | STOPBITS); newtio.c_lflag = 0; newtio.c_iflag = 0; newtio.c_cc[VTIME] = 10; /* inter-character timer set */ newtio.c_cc[VMIN] = 0; /* blocking read until 0 chars received */ tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &newtio); msg = "Temperature\n"; rc = send_serial(&fd,msg); msg = malloc(BUFSIZE); memset(msg, 0, sizeof(msg)); oldmsg = malloc(BUFSIZE); memset(oldmsg, 0, sizeof(oldmsg)); i = 1; while( (rc = read(fd,buf,BUFSIZE)) > 0) { oldmsg = msg; msg = (char *)malloc(BUFSIZE*i); bzero(msg,BUFSIZE*i); sprintf(msg,"%s%s", oldmsg, buf); i++; } if(rc < 0) { return -1; } close(fd); pattern = "\\d+\\.\\d"; re = pcre_compile(pattern,0,®error,®erroff,NULL); rc = pcre_exec( re, NULL, msg, BUFSIZE*i, 0, 0, ovector, BUFSIZE ); memset(buf, 0, BUFSIZE); length = strlen(msg); if(length < BUFSIZE) { strncpy(buf,oldmsg+ovector[0],ovector[1]-ovector[0]); } *temperature = strtod(buf,NULL); return 0; } void usage(int exit_code) { puts("Usage:\n"); puts("\tcheck_temp [options]\n"); puts("\t\t--warning-low\t\tLow warning threshhold"); puts("\t\t--warning-high\t\tHigh warning threshhold"); puts("\t\t--critical-low\t\tLow critical threshhold"); puts("\t\t--critical-high\t\tHigh critical threshhold"); puts("\t\t--serial-port\t\tSerial port device"); exit(exit_code); } int network(char *serial_port,int daemon_port) { int rc = 0; int s,b,len,n,on = 1; double temperature; char buf[BUFSIZE]; struct sockaddr_in channel; struct protoent *proto; struct sockaddr_in from; memset(&channel, 0, sizeof(channel)); channel.sin_family = AF_INET; channel.sin_addr.s_addr = htonl(INADDR_ANY); channel.sin_port = htons(daemon_port); proto = getprotobyname("udp"); s = socket(AF_INET, SOCK_DGRAM, proto->p_proto); if(s < 0) fatal("socket failed"); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)); b = bind(s, (struct sockaddr *) &channel, sizeof(channel)); if(b < 0) fatal("bind failed"); len = sizeof(struct sockaddr_in); while(1) { n = recvfrom(s,buf,BUFSIZE,0,(struct sockaddr *)&from,&len); if(n < 0) fatal("recvfrom failed"); if(strncmp("t", buf, 1) == 0 || strncmp("T", buf, 1) == 0) { n = fetch_temp(serial_port,&temperature); if(n < 0) { fatal("fetch_temp failed"); } sprintf(buf, "%f\n", temperature); n = sendto(s,buf,strlen(buf),0,(struct sockaddr *)&from,len); if(n < 0) { fatal("sendto fatal"); } } } return rc; } void fatal(char *string) { printf("%s\n", string); exit(-1); }