/* ---------------------------------------------------------------- * * report.c * * C-DIMM reporting * * 2011-05-02 Christoph C. Birk (birk@obs.carnegiescience.edu) * 2011-05-06 'both' request * 2012-05-09 watchdog * 2018-09-10 updated for new system * 2020-10-27 fix ppalunas * * ---------------------------------------------------------------- */ #define DEBUG 0 #define PREFUN __PRETTY_FUNCTION__ #define STATE_FILE "/tmp/cdimm_report.state" #define LOG_FILE "/tmp/cdimm_report.log" #define DOG_FILE "/tmp/cdimm_report.dog" /* ---------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #include #include /* ---------------------------------------------------------------- */ static char host[128]="139.229.111.6"; /* cdimm0 = 10.7.2.22 */ static int port=51001; static int report_state (int,const char*,const char*); static int report_log (int,const char*); static void mail_file(const char*,const char*,const char*); static void mail_dog (const char*,const char*); static void copy_file(const char*,const char*); static int mail_dog_flag=0; static int TCPIP_Request(int,const char*,char*,int); static int TCPIP_SingleRequest(const char*,u_short,const char*,char*,int); static int TCPIP_Send(int sock,const char *message); static int TCPIP_Receive(int sock,char* answer,int buflen,int timeout); static int TCPIP_Wait4Char(int sock,char* c,int timeout); static int TCPIP_CreateClientSocket(const char*,u_short); /* ---------------------------------------------------------------- */ int main(int argc,char** argv) { int i,n,err; char buf[128]; char addr[256]="",cmd[128]="",dest[512]=""; char dogs[256]="lcopers.techgroup,birk"; // todo lcopers not at SBS strcpy(dogs,"birk,ppalunas@carnegiescience.edu"); { extern char *optarg; /* parse command line */ extern int opterr,optopt,optind; opterr=0; while ((i=getopt(argc,argv,"a:c:d:g:h:p:")) != EOF) { switch (i) { case 'a': /* email address(s) */ strcpy(addr,optarg); break; case 'c': /* single command */ strcpy(cmd,optarg); break; case 'd': /* destination */ strcpy(dest,optarg); break; case 'g': /* dog email address(s) */ strcpy(dogs,optarg); break; case 'h': /* host */ strcpy(host,optarg); break; case 'p': /* port */ port = atoi(optarg); break; } } if (optind < argc) strcpy(cmd,argv[optind]); } if (!strcmp(cmd,"both")) { int sock; /* request state+log */ sock = TCPIP_CreateClientSocket(host,port); if (sock == -1) { /* cannot connect */ mail_dog(dogs,"connection failed"); } else { err = TCPIP_Request(sock,"report",buf,sizeof(buf)); if (!err) { if (strstr(buf,"IDLE") && strstr(buf,"day")) { /* request log */ (void)report_log(sock,addr); } n = report_state(sock,"",dest); /* and state */ if (n <= 0) mail_dog(dogs,"could not get state"); } else { mail_dog(dogs,"could not get report"); } /* endif(err) */ (void)close(sock); } } else if (!strcmp(cmd,"state")) { /* get C-DIMM state (full) */ i = report_state(0,addr,dest); if (i <= 0) mail_dog(dogs,"could not get state"); } else if (!strcmp(cmd,"log")) { /* get C-DIMM log */ n = report_log(0,addr); if (n < 0) mail_dog(dogs,"could not get log"); } else if (*cmd) { /* other command */ err = TCPIP_SingleRequest(host,port,cmd,buf,sizeof(buf)); if (err) fprintf(stderr,"err=%d\n",err); else fprintf(stdout,"%s\n",buf); } else { /* C-DIMM state (1 line) */ err = TCPIP_SingleRequest(host,port,"report",buf,sizeof(buf)); if (err) fprintf(stderr,"err=%d\n",err); else fprintf(stdout,"%s\n",buf); } if (mail_dog_flag && *dest) { FILE *fp; fp = fopen(STATE_FILE,"w"); if (fp) { fprintf(fp,"not available\n"); fclose(fp); copy_file(STATE_FILE,dest); } } return mail_dog_flag; } /* ---------------------------------------------------------------- */ static int report_state(int in_sock,const char* addr,const char* dest) { int err,sock=in_sock,i=0; char cmd[32],buf[128]; if (!sock) sock = TCPIP_CreateClientSocket(host,port); if (sock < 0) return -1; err = TCPIP_Request(sock,"report state",buf,sizeof(buf)); if (!err) { int n; /* request report */ n = atoi(buf); if (n > 0) { FILE *fp=NULL; fp = fopen(STATE_FILE,"w"); if (fp) { for (i=0; i 0) fprintf(stdout,"%s\n",buf); #endif } fclose(fp); } /* endif(fp) */ } /* endif(n > 0) */ } if (!in_sock) (void)close(sock); if (i > 0) { /* got it */ if (*addr) mail_file(STATE_FILE,addr,"DIMM state"); if (*dest) copy_file(STATE_FILE,dest); } /* endif(i) */ return i; } /* ---------------------------------------------------------------- */ static int report_log(int in_sock,const char* addr) { int err,sock=in_sock,i=0; char buf[128]=""; FILE *fp=NULL; #if (DEBUG > 0) fprintf(stderr,"%s(%d,%s)\n",PREFUN,in_sock,addr); #endif if (!sock) sock = TCPIP_CreateClientSocket(host,port); if (sock < 0) return -1; fp = fopen(LOG_FILE,"w"); if (fp) { do { err = TCPIP_Request(sock,"report log",buf,sizeof(buf)); if (err) break; if (!strncmp(buf,"@end",4)) break; fprintf(fp,"%s\n",buf); i++; #if (DEBUG > 0) fprintf(stdout,"%s\n",buf); #endif } while (strncmp(buf,"@end",4)); fclose(fp); } /* endif(fp) */ if (!in_sock) (void)close(sock); if ((i > 0) && (*addr)) { time_t ut; struct tm *lt; char tstr[32],subj[64]; ut = time(NULL)-12*3600; /* beginning of night */ lt = localtime(&ut); strftime(tstr,sizeof(tstr),"%Y-%m-%d",lt); sprintf(subj,"DIMM Telescope Report, %s",tstr); mail_file(LOG_FILE,addr,subj); } return i; } /* ---------------------------------------------------------------- */ static void mail_file(const char* file,const char* address,const char* subject) { char buffer[1024]; #if (DEBUG > 1) fprintf(stderr,"%s(%s,%s,'%s')\n",PREFUN,file,address,subject); #endif sprintf(buffer,"mail -s '%s' %s < %s",subject,address,file); system(buffer); } /* ---------------------------------------------------------------- */ static void mail_dog(const char* address,const char* text) { char subject[32]="DIMM Alert"; FILE *fp; struct stat sbuf; #if (DEBUG > 0) fprintf(stderr,"%s(%s,%s)\n",PREFUN,address,text); #endif mail_dog_flag = 1; if (stat(DOG_FILE,&sbuf) == 0) { if (time(NULL)-sbuf.st_mtime < 4*3600) return; } if ((fp = fopen(DOG_FILE,"w")) != NULL) { fprintf(fp,"Warning: Magellan DIMM unresponsive. Please check.\n"); if (!strcmp(address,"birk")) fprintf(fp,"(%s)\n",text); fclose(fp); } mail_file(DOG_FILE,address,subject); } /* ---------------------------------------------------------------- */ static void copy_file(const char* src,const char* dst) { char buffer[1024]; #if (DEBUG > 1) fprintf(stderr,"%s(%s,%s)\n",PREFUN,src,dst); #endif sprintf(buffer,"cp %s %s",STATE_FILE,dst); system(buffer); } /* ---------------------------------------------------------------- */ /* TCP/IP */ /* ---------------------------------------------------------------- */ static int TCPIP_Request(int sock,const char* cmd,char* ans,int len) { int err; #if (DEBUG > 1) fprintf(stderr,"%s(%d,%s,%p,%d)\n",PREFUN,sock,cmd,ans,len); #endif err = TCPIP_Send(sock,cmd); if (!err) err = TCPIP_Receive(sock,ans,len,5); return err; } /* ---------------------------------------------------------------- */ static int TCPIP_SingleRequest(const char* host,u_short port, const char* cmd,char* ans,int len) { int sock; int err=0; #if (DEBUG > 1) fprintf(stderr,"%s(%s:%d,%s,%p,%d)\n",PREFUN,host,port,cmd,ans,len); #endif sock = TCPIP_CreateClientSocket(host,port); if (sock == -1) return -1; if ((err=TCPIP_Send(sock,cmd)) == 0) { err = TCPIP_Receive(sock,ans,len,5); } (void)close(sock); return err; } /* ---------------------------------------------------------------- */ static int TCPIP_Send(int sock,const char *message) { int err; #if (DEBUG > 2) fprintf(stderr,"%s(%s)\n",PREFUN,message); #endif err = send(sock,message,strlen(message),0); return((err > 0) ? 0 : err); } /* ---------------------------------------------------------------- */ static int TCPIP_Receive(int sock,char* answer,int buflen,int timeout) { int err=0,i; #if (DEBUG > 2) fprintf(stderr,"%s(%d,%p,%d,%d)\n",PREFUN,sock,answer,buflen,timeout); #endif for (i=0; i return err; } /* ---------------------------------------------------------------- */ static int TCPIP_Wait4Char(int sock,char* c,int timeout) // [ms] { int r; fd_set rfd; struct timeval tout; #if (DEBUG > 3) fprintf(stderr,"%s(%d,%p,%d\n)",PREFUN,sock,c,timeout); #endif do { FD_ZERO(&rfd); FD_SET(sock,&rfd); tout.tv_sec = timeout/1000; tout.tv_usec = 1000*(timeout%1000); r = select(sock+1,&rfd,NULL,NULL,&tout); if (FD_ISSET(sock,&rfd)) break; } while (r > 0); if (r <= 0) return -1; r = recv(sock,c,1,0); if (r <= 0) return -1; return 0; } /* ---------------------------------------------------------------- */ #define RETRIES 5 static int TCPIP_CreateClientSocket(const char *hostname,u_short port) { int sock=-1,i,r; struct hostent *hostp; // Warning: from static data struct protoent *proto; // Warning: from static data struct sockaddr_in saddr; #if (DEBUG > 1) fprintf(stderr,"%s(%s,%d)\n",PREFUN,hostname,port); #endif hostp = gethostbyname(hostname); /* get host IP address */ if (hostp == NULL) return -1; proto = getprotobyname("tcp"); /* get protocol by name */ if (proto == NULL) return -1; memset((void*)&saddr,0,sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons((u_short)port); memcpy(&saddr.sin_addr,hostp->h_addr_list[0],hostp->h_length); for (i=0; ip_proto)) == -1) break; (void)fcntl(sock,F_SETFD,FD_CLOEXEC); r = connect(sock,(struct sockaddr *)&saddr,sizeof(saddr)); if (r != -1) break; /* connect to socket */ (void)close(sock); sock = -1; if (i < (RETRIES-1)) sleep(1); } // endfor(retries) return sock; } /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */