int main(int argc, char *argv[]) { int n; int ch; int method='I'; int ConfigRead; char *DaemonName; char ChipInfoStr[CHIP_STR_LEN]; unsigned int VendID; unsigned int ChipID; int LocalOnly; int sock; int sock6; int length; int ipv4_enable=1; struct sockaddr_in server; int msgsock; char buf[1024]; char outbuf[1024]; int rval; int selretval; int syserr; fd_set ready; struct servent *sp; unsigned long port; int psd = -1; struct sockaddr_in paddr; struct hostent *hent; struct itimerval tmo = {{0,0},{0,0}}; struct itimerval tmooff = {{0,0},{0,0}}; sock = 0; sock6 = 0; count = 0; tabout = 0; iter = 1; ConfigRead = 0; ReReadConfigFile = 0; ExitProgram = 0; UseVbat = 0; pushit = 0; quiet = 1; MonitorType = NO_CHIP; if ((sp = getservbyname("healthd", "tcp")) == NULL) { port = 1281; } else { port = ntohs(sp->s_port); } if (strchr(argv[0], '/')) { DaemonName = strrchr(argv[0], '/') + 1; } else { DaemonName=argv[0]; } /* * Set some defaults */ for (n=0; n<MAX_TYPES; n++) { active[n] = 0; fail_count[n] = 0; warn_level[n] = 2; warn_sent[n] = 0; fail_level[n] = 5; fail_sent[n] = 0; doWarn[n] = 0; doFail[n] = 0; } temp_warn[0] = '\0'; temp_fail[0] = '\0'; fan_warn[0] = '\0'; fan_fail[0] = '\0'; volt_warn[0] = '\0'; volt_fail[0] = '\0'; debug = 0; local = 0; LocalOnly = 0; while((ch=getopt(argc, argv, "12BDILSP:Vc:df:t:p:q")) != -1) { switch(ch){ case '1': MonitorType = W83781D; break; case '2': MonitorType = W83782D; break; case 'B': UseVbat = 1; break; case 'D': case 'd': debug = 1; break; case 'I': method='I'; break; case 'L': local = 1; break; case 'P': port = atoi(optarg); break; case 'S': method='S'; break; case 'V': fprintf(stderr, "Version %s\n", hdVERSION); exit(0); break; case 't': tabout = 1; break; case 'p': if ((psd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { (void)fprintf(stderr, "%s: cannot create push socket: %s\n", DaemonName, strerror(errno)); exit(1); } if (!(hent = gethostbyname(optarg))) { herror("Can't resolve hostname"); exit(1); } bzero(&paddr, sizeof(struct sockaddr_in)); paddr.sin_family = AF_INET; bcopy(hent->h_addr_list[0], &paddr.sin_addr.s_addr, sizeof(paddr.sin_addr.s_addr)); paddr.sin_port = htons(PUSH_PORT); if (connect(psd, (struct sockaddr*)&paddr, sizeof(struct sockaddr_in)) < 0) { (void)fprintf(stderr, "%s: connect failed: %s\n", DaemonName, strerror(errno)); exit(1); } pushit = 1; break; case 'c': count = atoi(optarg); if (count < 1) { count = 0; } debug = 1; break; case 'f': { int fd; if ((fd = open(optarg, O_RDONLY, 0)) < 0) { (void)fprintf(stderr, "%s: %s: %s\n", DaemonName, optarg, strerror(errno)); exit(1); } close(fd); strncpy(ConfigFile, optarg, MAXPATHLEN); ReadConfigFile (ConfigFile); ConfigRead = 1; } break; case 'q': quiet = 0; break; default: fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV] [-f configfile] [-c|t count] <seconds for sleep>"\ " (default %d sec)\n", DaemonName, DEFAULT_SEC); exit(1); } } if (ConfigRead == 0) { strncpy(ConfigFile, CONFIG_FILE, MAXPATHLEN); ReadConfigFile (ConfigFile); ConfigRead = 1; } if (argc > optind) { if((n = atoi(argv[optind])) > 0) { tmo.it_value.tv_sec = n; } else { fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV] [-f configfile] [-c|t count] <seconds for sleep>"\ " (default %d sec)\n", DaemonName, DEFAULT_SEC); exit(1); } } else { tmo.it_value.tv_sec = DEFAULT_SEC; } if (InitMBInfo(method) != 0) { perror("InitMBInfo"); exit(1); } if (RstChip() < 0) { perror("RstChip"); exit(1); } if (local || debug) { /* If debug mode or local mode don't open a socket */ LocalOnly = 1; } VendID = GetVendorID(); switch (VendID) { case 0x5CA3: ChipID = GetChipID_winbond(); switch (ChipID) { case 0x10: snprintf(ChipInfoStr, CHIP_STR_LEN, "WinBond Chip: W83781D"); if (MonitorType == NO_CHIP) MonitorType = W83781D; break; case 0x11: snprintf(ChipInfoStr, CHIP_STR_LEN, "Asus: AS97127F"); if (MonitorType == NO_CHIP) MonitorType = W83781D; break; case 0x21: snprintf(ChipInfoStr, CHIP_STR_LEN, "WinBond Chip: W83627HF"); if (MonitorType == NO_CHIP) MonitorType = W83627HF; break; case 0x30: snprintf(ChipInfoStr, CHIP_STR_LEN, "WinBond Chip: W83782D"); if (MonitorType == NO_CHIP) MonitorType = W83782D; break; case 0x40: snprintf(ChipInfoStr, CHIP_STR_LEN, "WinBond Chip: W83783S"); if (MonitorType == NO_CHIP) MonitorType = W83783S; break; default: snprintf(ChipInfoStr, CHIP_STR_LEN, "WinBond Chip: (unknown)"); if (MonitorType == NO_CHIP) MonitorType = W83781D; break; } break; case 0x12C3: snprintf(ChipInfoStr, CHIP_STR_LEN, "Asus: AS99127F"); if (MonitorType == NO_CHIP) MonitorType = AS99127F; break; case 0xFFFF0040: snprintf(ChipInfoStr, CHIP_STR_LEN, "National Semi: LM78"); if (MonitorType == NO_CHIP) MonitorType = LM78; break; case 0xFFFF00C0: snprintf(ChipInfoStr, CHIP_STR_LEN, "National Semi: LM79"); if (MonitorType == NO_CHIP) MonitorType = LM79; break; default: snprintf(ChipInfoStr, CHIP_STR_LEN, "Unknown Vendor: ID = %X", VendID); if (MonitorType == NO_CHIP) MonitorType = W83781D; break; } if (debug) { printf("************************\n"); printf("* Hardware Information *\n"); printf("************************\n"); printf("%s\n", ChipInfoStr); printf("************************\n\n"); } (void) openlog(DaemonName, LOG_CONS|LOG_NDELAY, hdFACILITY); signal(SIGALRM, SIGALRM_handler); if (debug == 0) { /* * Okay so far. Try and make ourself a daemon */ if (daemon(0,0) < 0) { syslog(hdALERT, "daemon libray call failed: %m (aborting)"); exit(2); } syslog(hdNOTICE, "Started"); } if (debug == 0) { /* Don't set the signal handler if we are in debug mode */ /* Since we don't check the ranges */ signal(SIGHUP, SIGHUP_handler); signal(SIGTERM, SIGTERM_handler); siginterrupt(SIGALRM,1); } if (LocalOnly == 0) { /* Create name with wildcards. */ if (ipv4_enable) { /* Create socket from which to read. */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { syslog(hdALERT, "opening datagram socket: %m"); syslog(hdALERT, "Aborting"); exit(1); } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(port); if (bind(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in))) { close(sock); syslog(hdALERT, "binding datagram socket: %m"); syslog(hdALERT, "Aborting"); exit(1); } /* Find assigned port value and print it out. */ length = sizeof(server); if (getsockname(sock, (struct sockaddr *)&server, &length)) { close(sock); syslog(hdALERT, "getting socket name: %m"); syslog(hdALERT, "Aborting"); exit(1); } } } ReadCurrentValues(); if (LocalOnly == 0) { /* Start accepting connections */ if (sock != 0) { listen(sock, 32); } } /* Main daemon loop */ while ((iter<count) || (count==0)) { FD_ZERO(&ready); if (LocalOnly == 0) { if (sock != 0) { FD_SET(sock, &ready); } } /* Wait for connection, or timeout */ setitimer(ITIMER_REAL,&tmo,0); selretval = select(getdtablesize(), &ready, 0, 0, 0); syserr = errno; setitimer(ITIMER_REAL,&tmooff,0); if ( ExitProgram ) { break; } switch (selretval) { case -1: if (syserr && syserr != EINTR) { syslog(hdCRITICAL, "OOPS! select returned a weird error, bailing out: %m"); exit(1); } if (ReReadConfigFile) { /* * If we are updating the config file * then we should clear the error counts. */ for (n=0; n<MAX_TYPES; n++) { active[n] = 0; fail_count[n] = 0; warn_level[n] = 2; warn_sent[n] = 0; fail_level[n] = 5; fail_sent[n] = 0; } ReadConfigFile (ConfigFile); ReReadConfigFile = 0; syslog(hdWARNING, "Restarted"); break; } if (count > 0) { iter++; } ReadCurrentValues(); if (pushit) { push_stat(psd); } break; default: if (LocalOnly == 0) { if (FD_ISSET(sock, &ready)) { msgsock = accept(sock, 0, 0); if (msgsock == -1) { /* Add error handling here */ } else { do { bzero(buf, sizeof(buf)); bzero(outbuf, sizeof(outbuf)); if ((rval = read(msgsock, buf, 1024)) > 0) { rval = GetAnswer(buf, outbuf); write(msgsock, outbuf, strlen(outbuf)); } else if (rval < 0) { break; } } while (rval != 0); close(msgsock); } } } break; } if (ExitProgram) { break; } } if (LocalOnly == 0) { close(sock); } if (debug == 0) { signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); } syslog(hdWARNING, "Exiting.."); exit(0); }
int init(void) { struct sockaddr_in from, to; const char *msg; int i, idx; FILE *in; if (!HAVE_OPT(OUTPUT)) { LOG(LOG_ERR, "missing output option"); return 0; } if (OPT_VALUE_SERVERID == 0) { fprintf(stderr, "Please set serverid first\n"); return 0; } if (HAVE_OPT(ERRLOG)) { int ct = STACKCT_OPT(ERRLOG); char **errlog = (char **) &STACKLST_OPT(ERRLOG); for (idx=0, i=0; i < ct && idx < 255; i++) { char *start, *end; start = end = errlog[i]; while (*end && !isspace(*end)) { end++; } if (!*end) { LOG(LOG_WARNING, "Illegal format: %s", errlog[i]); continue; } *end++ = 0; errlogspec[idx].style = start; while (*end && isspace(*end)) { end++; } if (!*end) { LOG(LOG_WARNING, "Illegal format: %s", errlog[i]); continue; } start = end; while (*end && !isspace(*end)) { end++; } *end = 0; errlogspec[idx++].path = start; } #if HAVE_LIBPCRE in = fopen(STATFILE, "r"); if (in) { while (!feof(in)) { char path[PATH_MAX]; long long offset; int i; if (fscanf(in, "%s %Ld", path, &offset) != 2) continue; for (i=0; errlogspec[i].path; i++) { if (strcmp(errlogspec[i].path, path)) continue; errlogspec[i].offset = offset; break; } } fclose(in); } #endif } #if USE_XMBMON if (OPT_VALUE_HWSTATS) { if (OPT_VALUE_TYAN_TIGER_MP) { TyanTigerMP_flag = 1; } if ((i = InitMBInfo(' ')) != 0) { LOG(LOG_ERR, "InitMBInfo: %m"); if (i < 0) { LOG(LOG_ERR,"This program needs setuid root"); } } } else { LOG(LOG_INFO,"Hardware stats will not be generated"); } #endif // determine ip address for default gateway interface setsin(&to, inet_addr("1.1.1.1")); msg = findsaddr(&to, &from); if (msg) { LOG(LOG_INFO, (char *)msg); strcpy(ipaddress, OPT_ARG(IPADDRESS)); } else { strcpy(ipaddress, inet_ntoa(from.sin_addr)); } LOG(LOG_INFO, "using ipaddress %s", ipaddress); daemonize = TRUE; every = EVERY_SECOND; xmlSetGenericErrorFunc(NULL, UpwatchXmlGenericErrorFunc); sleep(2); // ensure we wait until the next minute setpriority(PRIO_PROCESS, 0, 5); // we are not very important - be nice to other processes return 1; }