Skip to content

Instantly share code, notes, and snippets.

@hedgeven
Last active April 16, 2020 04:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hedgeven/1d95b0fc4e0aaf08e23d to your computer and use it in GitHub Desktop.
Save hedgeven/1d95b0fc4e0aaf08e23d to your computer and use it in GitHub Desktop.
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* main.c
* Copyright (C) 2014 Vassiliy K <hedgeven@linux.com>
*
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/stat.h>
#include <sysexits.h>
#include <time.h>
#include <utime.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <syslog.h>
#include <ctype.h>
#define BUFFSIZE 4096
#define EXPIRE_TIME 8 // Timeout to update the cache file
#define SOCK_TIMEOUT 3 // Timeout to blocking socket operations
#define CTRL_TIMEOUT 3 // Timeout to wait for data from the controller
#define DEFAULT_PORT 1000
#define GET_PORT "get_port\r\n"
#define GET_T "get_t\r\n"
#define CACHEDIR "/var/cache/zabbix/mka2/"
static char *args;
static char msg[200];
int main(int argc, char **argv)
{
int port = DEFAULT_PORT;
int uptate_status;
int i;
int argl = 0;
char *cache_dir = CACHEDIR;
char *host;
char cache_file[100];
char pattern[20];
char result[10];
struct stat dst, fst;
struct utimbuf t;
FILE *fp;
setlogmask (LOG_UPTO (LOG_NOTICE));
openlog ("mka2", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
for (i = 0; i<argc; i++)
argl+=((int)(strlen(argv[i])) + 1);
args = (char *) malloc(argl);
for (i = 0; i<argc; i++) {
strcat(args, argv[i]);
if (argc != i+1) strcat(args, " ");
}
// Analysis of parameters
if (argc > 1) {
/* Parse first parameter as search pattern.
* ^[0-2].$ - Port #.{1,2}
* ^T.$ - T_sensor #.
*/
char num[3];
if (isdigit(argv[1][0])) {
strcpy(pattern, "Port # ");
sscanf(argv[1], "%2s", num);
} else if (argv[1][0] == 'T' && isdigit(argv[1][1])) {
strcpy(pattern, "T_sensor #");
sscanf(argv[1], "T%1s", num);
} else {
sprintf (msg, "%s: Invalid search pattern %s\n", args, argv[1]);
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_USAGE);
}
strcat(pattern, num);
strcat(pattern, " = ");
// Parse second parameter as ip address.
if (argc > 2)
host = argv[2];
else {
sprintf (msg, "Host is not specified\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_USAGE);
}
// Parse third parameter as port.
if (argc > 3)
port = atoi(argv[3]);
} else {
printf("Usage: mta2 pattern host [port]\n");
return (EX_USAGE);
}
// Create cache directory
if (stat(cache_dir, &dst) == -1)
if (mkdir(cache_dir, 0755)) {
sprintf (msg, "No access to the %s\n", cache_dir);
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_NOPERM);
}
// Create cache file if not exists and get data
strcpy(cache_file, cache_dir);
strcat(cache_file, host);
if ((stat(cache_file, &fst) == -1)) {
if ((fp = fopen(cache_file, "a")) == NULL) {
sprintf (msg, "No access to the %s\n", cache_file);
return (EX_NOPERM);
} else {
fclose(fp);
if (uptate_status = cache_update(host, port, cache_file))
return (uptate_status);
}
}
// If the cache is out of date, then update it
if (difftime(time(NULL), fst.st_mtime) > EXPIRE_TIME) {
t.modtime = time(NULL);
utime(cache_file, &t);
if (uptate_status = cache_update(host, port, cache_file))
return (uptate_status);
}
if ((fp = fopen(cache_file, "r")) == NULL) {
sprintf (msg, "No access to the %s\n", cache_file);
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_NOPERM);
} else {
char l[BUFFSIZE];
while(fgets(l, BUFFSIZE, fp))
if (strstr(l, pattern) != NULL)
sscanf(l, strcat(pattern, "%s"), result);
fclose(fp);
}
if (isdigit(result[0]))
printf ("%s\n", result);
else
printf ("%s\n", "No data");
closelog ();
return (EX_OK);
}
int cache_update(char *host, int port, char *file)
{
int sockfd;
char buffer[BUFFSIZE];
char result[BUFFSIZE*2];
FILE *fp;
struct sockaddr_in serv_addr;
struct hostent *server;
struct timeval timeout;
timeout.tv_sec = SOCK_TIMEOUT;
timeout.tv_usec = 0;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
sprintf (msg, "Error opening socket\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
if ((server = gethostbyname(host)) == NULL) {
sprintf (msg, "No such host %s\n", host);
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_NOHOST);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(port);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
sprintf (msg, "Error connecting to %s:%d\n", host, port);
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout)) < 0)
syslog (LOG_ERR, "%s: setsockopt failed\n", args);
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
sizeof(timeout)) < 0)
syslog (LOG_ERR, "%s: setsockopt failed\n", args);
if ((read(sockfd,buffer,BUFFSIZE-1)) < 0) {
sprintf (msg, "Error reading from socket\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
bzero(buffer,BUFFSIZE);
if ((write(sockfd,GET_PORT,strlen(GET_PORT))) < 0) {
sprintf (msg, "Error writing to socket\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
sleep (CTRL_TIMEOUT);
if ((read(sockfd,buffer,BUFFSIZE-1)) < 0) {
sprintf (msg, "Error Reading from socket\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
strcat(result, buffer);
bzero(buffer,BUFFSIZE);
if ((write(sockfd,GET_T,strlen(GET_T))) < 0) {
sprintf (msg, "Error writing to socket\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
sleep (CTRL_TIMEOUT);
if ((read(sockfd,buffer,BUFFSIZE-1)) < 0) {
sprintf (msg, "Error Reading from socket\n");
printf ("%s", msg);
syslog (LOG_ERR, "%s: %s", args, msg);
return (EX_PROTOCOL);
}
strcat(result, buffer);
if ((fp = fopen(file, "w")) != NULL) {
fputs(result, fp);
fclose(fp);
} else
return (EX_NOPERM);
close(sockfd);
return (EX_OK);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment