static int serialReadExact (WVIEW_MEDIUM *med, void *bfr, int len, int msTimeout) { int rval, cumTime = 0, index = 0; uint64_t readTime; uint8_t *ptr = (uint8_t *)bfr; while (index < len && cumTime < msTimeout) { readTime = radTimeGetMSSinceEpoch (); rval = read (med->fd, &ptr[index], len - index); if (rval < 0) { if (errno != EINTR && errno != EAGAIN) { return ERROR; } } else { index += rval; } readTime = radTimeGetMSSinceEpoch () - readTime; cumTime += (int)readTime; if (index < len && cumTime < msTimeout) { readTime = radTimeGetMSSinceEpoch (); radUtilsSleep (9); readTime = radTimeGetMSSinceEpoch () - readTime; cumTime += (int)readTime; } } return ((index == len) ? len : ERROR); }
// ... Tick off delta time and run timeout routines as needed static int serviceTimers (int ifProcessExpiredTimers) { ULONG numberOfTicks, smallestDelta; // is this the first time? if (timerList->lastTick == 0ULL) { timerList->lastTick = radTimeGetMSSinceEpoch (); } numberOfTicks = (ULONG)(radTimeGetMSSinceEpoch () - timerList->lastTick); timerList->lastTick = radTimeGetMSSinceEpoch (); // update timers with number of expired ticks smallestDelta = updateTimers (numberOfTicks); if (ifProcessExpiredTimers && smallestDelta == 0) { // process expired timer(s) processExpiredTimers (); // re-process timers with zero ticks to get smallest delta value smallestDelta = updateTimers (0); } return smallestDelta; }
static void timerHandler (void *parm) { uint64_t msOffset = radTimeGetMSSinceEpoch (); int64_t netOffset; // ... allow for timer latency if (sshWork.msOffset == 0ULL) { // first time through sshWork.msOffset = msOffset; netOffset = 0LL; } else { netOffset = msOffset - sshWork.msOffset; } sshWork.msOffset += 60000ULL; // ALWAYS 1 minute radProcessTimerStart (sshWork.timer, (uint32_t)(60000LL - netOffset)); // ... process the ssh rules sshUtilsSendFiles (sshWork.sshId, sshWork.wviewdir); return; }
static void timerHandler (void *parm) { ULONGLONG msOffset = radTimeGetMSSinceEpoch (); int rules; long long netOffset; // ... allow for timer latency if (ftpWork.msOffset == 0) { // first time through ftpWork.msOffset = msOffset; netOffset = 0; } else { netOffset = msOffset - ftpWork.msOffset; while (netOffset >= 60000LL) { netOffset -= 60000LL; } } while (ftpWork.msOffset < msOffset) { ftpWork.msOffset += 60000ULL; } radProcessTimerStart(ftpWork.timer, (ULONG)(60000LL - netOffset)); // ... process the ftp rules rules = ftpUtilsSendFiles(ftpWork.ftpId, ftpWork.wviewdir); if (rules > 0) { wvutilsLogEvent (PRI_STATUS, "FTP: %d rules processed", rules); } else if (rules < 0) { wvutilsLogEvent (PRI_MEDIUM, "FTP: ftpUtilsSendFiles failed!"); } return; }
static void timerHandler (void *parm) { uint64_t msOffset = radTimeGetMSSinceEpoch (); int64_t netOffset; uint64_t xoffset; // ... allow for timer latency if (sshWork.msOffset == 0ULL) { // first time through sshWork.msOffset = msOffset; netOffset = 0LL; } else { netOffset = msOffset - sshWork.msOffset; } sshWork.msOffset += 60000ULL; // ALWAYS 1 minute xoffset = sshWork.msOffset; // Cope with long scheduling delays or with the time being changed int32_t timerWait = (int32_t)(60000LL - netOffset); if ((timerWait <= 0) || (timerWait > 120000)) { radMsgLog (PRI_HIGH, "wviewsshd: unusual wait %d; fixing it up", timerWait); // Keep the offset into the minute to keep updates aligned with the original alignment. uint64_t baseNow = (msOffset / 60000ULL) * 60000ULL; netOffset = 60000ULL; sshWork.msOffset = baseNow + netOffset + (sshWork.msOffset % 60000ULL); radMsgLog (PRI_HIGH, "wviewsshd: fixed offset is %llu", sshWork.msOffset); } radProcessTimerStart (sshWork.timer, (uint32_t)(60000LL - netOffset)); // ... process the ssh rules sshUtilsSendFiles (sshWork.sshId, sshWork.wviewdir); return; }
/* ... the main entry point for the daemon process */ int main (int argc, char *argv[]) { void (*alarmHandler)(int); FILE *pidfile; int iValue; double dValue; const char* sValue; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } /* ... start with a clean slate */ memset (&wviewdWork, 0, sizeof (wviewdWork)); /* ... initialize some system stuff first */ if (daemonSysInit (&wviewdWork) == -1) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "system init failed!\n"); radMsgLogExit (); exit (1); } /* ... call the global radlib system init function */ if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_DAEMON, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } /* ... call the radlib process init function */ if (radProcessInit (PROC_NAME_DAEMON, wviewdWork.fifoFile, PROC_NUM_TIMERS_DAEMON, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_DAEMON); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.myPid = getpid (); pidfile = fopen (wviewdWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!\n"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (defaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); radMsgLog (PRI_STATUS, "%s starting ...", globalWviewVersionStr); radTimeGetMSSinceEpoch(); wvutilsDetectDSTInit(); // get our configuration values: if (wvconfigInit(TRUE) == ERROR) { radMsgLog (PRI_CATASTROPHIC, "config database is missing!!!\n"); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // get the wview verbosity setting if (wvutilsSetVerbosity (WV_VERBOSE_WVIEWD) == ERROR) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "wvutilsSetVerbosity failed!"); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } ///// STATION_INTERFACE PROCESSING BEGIN ///// sValue = wvconfigGetStringValue(configItem_STATION_STATION_TYPE); if (sValue == NULL) { radMsgLog (PRI_MEDIUM, "no station type given, defaulting to 'VantagePro'..."); strcpy (wviewdWork.stationType, "VantagePro"); } else { wvstrncpy(wviewdWork.stationType, sValue, sizeof(wviewdWork.stationType)); } if ((!strcmp(wviewdWork.stationType, "WMRUSB")) || (!strcmp(wviewdWork.stationType, "WH1080"))) { // USB stations: radMsgLog (PRI_MEDIUM, "station interface: native USB ..."); } else { sValue = wvconfigGetStringValue(configItem_STATION_STATION_INTERFACE); if (sValue == NULL) { radMsgLog (PRI_MEDIUM, "no station interface given, defaulting to 'serial'..."); strcpy (wviewdWork.stationInterface, "serial"); } else { wvstrncpy(wviewdWork.stationInterface, sValue, sizeof(wviewdWork.stationInterface)); } // process the interface type if (!strcmp (wviewdWork.stationInterface, "serial")) { radMsgLog (PRI_MEDIUM, "station interface: serial ..."); // we need a device name for serial IFs sValue = wvconfigGetStringValue(configItem_STATION_STATION_DEV); if (sValue == NULL) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "no serial device given, aborting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy(wviewdWork.stationDevice, sValue, sizeof(wviewdWork.stationDevice)); } // grab the DTR toggle flag: iValue = wvconfigGetBooleanValue(configItem_STATION_STATION_DTR); if (iValue >= 0) { wviewdWork.stationToggleDTR = iValue; } else { wviewdWork.stationToggleDTR = TRUE; } } else if (!strcmp (wviewdWork.stationInterface, "ethernet")) { radMsgLog (PRI_MEDIUM, "station interface: ethernet ..."); // we need host and port for ethernet sValue = wvconfigGetStringValue(configItem_STATION_STATION_HOST); if (sValue == NULL) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "no hostname given, aborting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wvstrncpy(wviewdWork.stationHost, sValue, sizeof(wviewdWork.stationHost)); iValue = wvconfigGetINTValue(configItem_STATION_STATION_PORT); if (iValue <= 0) { wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "no port given, aborting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { wviewdWork.stationPort = iValue; // grab the Weatherlink IP flag: iValue = wvconfigGetBooleanValue(configItem_STATION_STATION_WLIP); if (iValue >= 0) { wviewdWork.stationIsWLIP = iValue; } else { wviewdWork.stationIsWLIP = FALSE; } } } } else { // invalid type specified - abort wvconfigExit(); radMsgLog (PRI_CATASTROPHIC, "invalid STATION_INTERFACE %s given, aborting...", wviewdWork.stationInterface); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } } ///// STATION_INTERFACE PROCESSING END ///// iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_SEASON_START); if (iValue <= 0) { radMsgLog (PRI_MEDIUM, "Rain Season Start Month not found - defaulting to 1 (JAN)...\n"); wviewdWork.stationRainSeasonStart = 1; } else { wviewdWork.stationRainSeasonStart = iValue; if (wviewdWork.stationRainSeasonStart < 1 || wviewdWork.stationRainSeasonStart > 12) { radMsgLog (PRI_MEDIUM, "Invalid Rain Season Start Month %d found - defaulting to 1 (JAN)...\n", wviewdWork.stationRainSeasonStart); wviewdWork.stationRainSeasonStart = 1; } else { radMsgLog (PRI_STATUS, "Rain Season Start Month set to %d\n", wviewdWork.stationRainSeasonStart); } } dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_RAIN_STORM_TRIGGER_START); if (dValue <= 0.0) { radMsgLog (PRI_MEDIUM, "no rain storm start trigger given, defaulting to 0.05 in/hr..."); wviewdWork.stationRainStormTrigger = 0.05; } else { wviewdWork.stationRainStormTrigger = (float)dValue; radMsgLog (PRI_STATUS, "Rain Storm Start Trigger set to %5.2f in/hr\n", wviewdWork.stationRainStormTrigger); } iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_STORM_IDLE_STOP); if (iValue <= 0) { radMsgLog (PRI_MEDIUM, "no rain storm idle stop time given, defaulting to 12 hours..."); wviewdWork.stationRainStormIdleHours = 12; } else { wviewdWork.stationRainStormIdleHours = iValue; radMsgLog (PRI_STATUS, "Rain Storm Stop Time set to %d hours\n", wviewdWork.stationRainStormIdleHours); } dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_RAIN_YTD); if (dValue < 0.0) { radMsgLog (PRI_MEDIUM, "no rain YTD preset given, defaulting to 0.00 inches..."); wviewdWork.stationRainStormIdleHours = 12; } else { wviewdWork.stationRainYTDPreset = (float)dValue; radMsgLog (PRI_STATUS, "Rain YTD preset set to %.2f inches\n", wviewdWork.stationRainYTDPreset); } dValue = wvconfigGetDOUBLEValue(configItem_STATION_STATION_ET_YTD); if (dValue < 0.0) { radMsgLog (PRI_MEDIUM, "no ET YTD preset given, defaulting to 0.000 inches..."); wviewdWork.stationETYTDPreset = 0; } else { wviewdWork.stationETYTDPreset = (float)dValue; radMsgLog (PRI_STATUS, "ET YTD preset set to %.3f inches\n", wviewdWork.stationETYTDPreset); } iValue = wvconfigGetINTValue(configItem_STATION_STATION_RAIN_ET_YTD_YEAR); if (iValue < 0) { radMsgLog (PRI_MEDIUM, "no rain/ET YTD Year given, disabling..."); wviewdWork.stationRainETPresetYear = 0; } else { wviewdWork.stationRainETPresetYear = iValue; if (wviewdWork.stationRainETPresetYear < 2000 || wviewdWork.stationRainETPresetYear > 3000) { radMsgLog (PRI_MEDIUM, "bad rain/ET YTD Year given, disabling..."); wviewdWork.stationRainETPresetYear = 0; } else { radMsgLog (PRI_STATUS, "rain/ET YTD preset Year set to %d\n", wviewdWork.stationRainETPresetYear); } } iValue = wvconfigGetINTValue(configItem_STATION_POLL_INTERVAL); if (iValue < 0) { radMsgLog (PRI_MEDIUM, "no POLL_INTERVAL retrieved, setting to 30 seconds..."); wviewdWork.cdataInterval = 30000; } else { wviewdWork.cdataInterval = iValue * 1000; } if (((wviewdWork.cdataInterval % 1000) != 0) || ((wviewdWork.cdataInterval/1000) > 60) || ((60 % (wviewdWork.cdataInterval/1000)) != 0)) { radMsgLog (PRI_MEDIUM, "station polling interval %d found in wview.conf is invalid:", wviewdWork.cdataInterval); radMsgLog (PRI_MEDIUM, "defaulting to 30 seconds ..."); radMsgLog (PRI_MEDIUM, "Note: station polling interval must be less than 60 seconds"); radMsgLog (PRI_MEDIUM, " and an even divisor of 60 seconds (10000, 15000, 30000)"); wviewdWork.cdataInterval = 30 * 1000; } else { radMsgLog (PRI_STATUS, "station polling interval set to %d seconds", (wviewdWork.cdataInterval/1000)); } iValue = wvconfigGetINTValue(configItem_STATION_PUSH_INTERVAL); if (iValue < 0) { radMsgLog (PRI_MEDIUM, "no PUSH_INTERVAL retrieved, setting to 60 seconds..."); wviewdWork.pushInterval = 60000; } else { wviewdWork.pushInterval = iValue * 1000; } // Calibration configuration: dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_BAROMETER); if (dValue <= 0.0) { wviewdWork.calMBarometer = 1.00; } else { wviewdWork.calMBarometer = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_BAROMETER); wviewdWork.calCBarometer = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_PRESSURE); if (dValue <= 0.0) { wviewdWork.calMPressure = 1.00; } else { wviewdWork.calMPressure = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_PRESSURE); wviewdWork.calCPressure = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_ALTIMETER); if (dValue <= 0.0) { wviewdWork.calMAltimeter = 1.00; } else { wviewdWork.calMAltimeter = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_ALTIMETER); wviewdWork.calCAltimeter = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_INTEMP); if (dValue <= 0.0) { wviewdWork.calMInTemp = 1.00; } else { wviewdWork.calMInTemp = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_INTEMP); wviewdWork.calCInTemp = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_OUTTEMP); if (dValue <= 0.0) { wviewdWork.calMOutTemp = 1.00; } else { wviewdWork.calMOutTemp = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_OUTTEMP); wviewdWork.calCOutTemp = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_INHUMIDITY); if (dValue <= 0.0) { wviewdWork.calMInHumidity = 1.00; } else { wviewdWork.calMInHumidity = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_INHUMIDITY); wviewdWork.calCInHumidity = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_OUTHUMIDITY); if (dValue <= 0.0) { wviewdWork.calMOutHumidity = 1.00; } else { wviewdWork.calMOutHumidity = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_OUTHUMIDITY); wviewdWork.calCOutHumidity = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_WINDSPEED); if (dValue <= 0.0) { wviewdWork.calMWindSpeed = 1.00; } else { wviewdWork.calMWindSpeed = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_WINDSPEED); wviewdWork.calCWindSpeed = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_WINDDIR); if (dValue <= 0.0) { wviewdWork.calMWindDir = 1.00; } else { wviewdWork.calMWindDir = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_WINDDIR); wviewdWork.calCWindDir = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_RAIN); if (dValue <= 0.0) { wviewdWork.calMRain = 1.00; } else { wviewdWork.calMRain = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_RAIN); wviewdWork.calCRain = dValue; dValue = wvconfigGetDOUBLEValue(configItemCAL_MULT_RAINRATE); if (dValue <= 0.0) { wviewdWork.calMRainRate = 1.00; } else { wviewdWork.calMRainRate = dValue; } dValue = wvconfigGetDOUBLEValue(configItemCAL_CONST_RAINRATE); wviewdWork.calCRainRate = dValue; iValue = wvconfigGetBooleanValue(configItem_ENABLE_EMAIL); if (iValue >= 0) { wviewdWork.IsAlertEmailsEnabled = iValue; } if (wviewdWork.IsAlertEmailsEnabled) { sValue = wvconfigGetStringValue(configItem_TO_EMAIL_ADDRESS); if (sValue == NULL) { radMsgLog (PRI_HIGH, "NO alert email TO address given - disabling email alerts..."); wviewdWork.IsAlertEmailsEnabled = 0; } else { wvstrncpy (wviewdWork.alertEmailToAdrs, sValue, sizeof(wviewdWork.alertEmailToAdrs)); } sValue = wvconfigGetStringValue(configItem_FROM_EMAIL_ADDRESS); if (sValue == NULL) { radMsgLog (PRI_HIGH, "NO alert email FROM address given - disabling email alerts..."); wviewdWork.IsAlertEmailsEnabled = 0; } else { wvstrncpy (wviewdWork.alertEmailFromAdrs, sValue, sizeof(wviewdWork.alertEmailFromAdrs)); } iValue = wvconfigGetBooleanValue(configItem_SEND_TEST_EMAIL); if (iValue >= 0) { wviewdWork.IsTestEmailEnabled = iValue; } } iValue = wvconfigGetBooleanValue(configItem_HTMLGEN_STATION_SHOW_IF); if (iValue >= 0) { wviewdWork.showStationIF = iValue; } else { wviewdWork.showStationIF = TRUE; } wvconfigExit (); if (statusInit(wviewdWork.statusFile, wviewStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "statusInit failed - exiting..."); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); // ... Initialize the archive database interface: if (dbsqliteArchiveInit() == ERROR) { radMsgLog (PRI_HIGH, "dbsqliteArchiveInit failed"); statusUpdateMessage("dbsqliteArchiveInit failed"); statusUpdate(STATUS_ERROR); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // Initialize timers: wviewdWork.archiveTimer = radTimerCreate (NULL, archiveTimerHandler, NULL); if (wviewdWork.archiveTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.cdataTimer = radTimerCreate (NULL, cdtimerHandler, NULL); if (wviewdWork.cdataTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.pushTimer = radTimerCreate (NULL, pushTimerHandler, NULL); if (wviewdWork.pushTimer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.syncTimer = radTimerCreate (NULL, syncTimerHandler, NULL); if (wviewdWork.syncTimer == NULL) { radMsgLog (PRI_HIGH, "sync radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } wviewdWork.ifTimer = radTimerCreate (NULL, ifTimerHandler, NULL); if (wviewdWork.ifTimer == NULL) { radMsgLog (PRI_HIGH, "sync radTimerCreate failed"); statusUpdateMessage("radTimerCreate failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } radProcessEventsAdd (STATION_INIT_COMPLETE_EVENT); radProcessEventsAdd (STATION_LOOP_COMPLETE_EVENT); // register with the radlib message router if (radMsgRouterInit (WVIEW_RUN_DIR) == ERROR) { radMsgLog (PRI_HIGH, "radMsgRouterInit failed!"); statusUpdateMessage("radMsgRouterInit failed"); statusUpdate(STATUS_ERROR); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // enable message reception from the radlib router for worker requests radMsgRouterMessageRegister (WVIEW_MSG_TYPE_REQUEST); // enable message reception from the radlib router for POLL msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_POLL); // enable message reception from the radlib router for ALERT msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_ALERT); // enable message reception from the radlib router for STATION_DATA msgs radMsgRouterMessageRegister (WVIEW_MSG_TYPE_STATION_DATA); // Initialize the HILOW database interface: // (this cannot occur before the MsgRouter is initialized) if (dbsqliteHiLowInit(TRUE) == ERROR) { radMsgLog (PRI_HIGH, "dbsqliteHiLowInit failed"); statusUpdateMessage("dbsqliteHiLowInit failed"); statusUpdate(STATUS_ERROR); stationSendShutdown(&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // initialize the station abstraction radMsgLog (PRI_STATUS, "-- Station Init Start --"); if (stationInit (&wviewdWork, daemonArchiveIndication) == ERROR) { radMsgLog (PRI_HIGH, "stationInit failed!"); statusUpdateMessage("stationInit failed"); statusUpdate(STATUS_ERROR); stationSendShutdown(&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // register the station interface if it is device-based: if (wviewdWork.medium.type == MEDIUM_TYPE_DEVICE) { if (radProcessIORegisterDescriptor (wviewdWork.medium.fd, stationDataCallback, NULL) == ERROR) { radMsgLog (PRI_HIGH, "IORegDescriptor failed"); statusUpdateMessage("IORegDescriptor failed"); statusUpdate(STATUS_ERROR); stationSendShutdown(&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.archiveTimer); stationExit (&wviewdWork); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } } // Send test email if it is enabled: if (wviewdWork.IsTestEmailEnabled) { radMsgLog(PRI_STATUS, "Sending test email..."); emailAlertSend(ALERT_TYPE_TEST); } statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); radMsgLog (PRI_STATUS, "running..."); while (!wviewdWork.exiting) { // wait on timers, events, file descriptors, msgs if (radProcessWait (0) == ERROR) { wviewdWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); computedDataExit (&wviewdWork); radMsgRouterExit (); radTimerDelete (wviewdWork.ifTimer); radTimerDelete (wviewdWork.syncTimer); radTimerDelete (wviewdWork.pushTimer); radTimerDelete (wviewdWork.cdataTimer); radTimerDelete (wviewdWork.archiveTimer); stationExit (&wviewdWork); dbsqliteHiLowExit(); dbsqliteArchiveExit(); daemonSysExit (&wviewdWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
/* ... the main entry point for the ssh process */ int main (int argc, char *argv[]) { void (*alarmHandler)(int); STIM stim; int i; int seconds; time_t ntime; struct tm locTime; int offset, retVal; long msOffset; FILE *pidfile; int runAsDaemon = TRUE; if (argc > 1) { if (!strcmp(argv[1], "-f")) { runAsDaemon = FALSE; } } memset (&sshWork, 0, sizeof (sshWork)); /* ... initialize some system stuff first */ retVal = sshSysInit (&sshWork); if (retVal == ERROR) { radMsgLogInit (PROC_NAME_SSH, FALSE, TRUE); radMsgLog (PRI_CATASTROPHIC, "ssh init failed!"); radMsgLogExit (); exit (1); } else if (retVal == ERROR_ABORT) { exit (2); } /* ... call the global radlib system init function */ if (radSystemInit (WVIEW_SYSTEM_ID) == ERROR) { radMsgLogInit (PROC_NAME_SSH, TRUE, TRUE); radMsgLog (PRI_CATASTROPHIC, "radSystemInit failed!"); radMsgLogExit (); exit (1); } /* ... call the radlib process init function */ if (radProcessInit (PROC_NAME_SSH, sshWork.fifoFile, PROC_NUM_TIMERS_SSH, runAsDaemon, // TRUE for daemon msgHandler, evtHandler, NULL) == ERROR) { printf ("\nradProcessInit failed: %s\n\n", PROC_NAME_SSH); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } sshWork.myPid = getpid (); pidfile = fopen (sshWork.pidFile, "w"); if (pidfile == NULL) { radMsgLog (PRI_CATASTROPHIC, "lock file create failed!"); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } fprintf (pidfile, "%d", getpid ()); fclose (pidfile); alarmHandler = radProcessSignalGetHandler (SIGALRM); radProcessSignalCatchAll (SSHDefaultSigHandler); radProcessSignalCatch (SIGALRM, alarmHandler); radProcessSignalRelease(SIGABRT); sshWork.timer = radTimerCreate (NULL, timerHandler, NULL); if (sshWork.timer == NULL) { radMsgLog (PRI_HIGH, "radTimerCreate failed - exiting"); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } // ... initialize the ssh utilities retVal = sshUtilsInit (&sshWork.sshData); if (retVal != OK) { if (retVal == ERROR) { radMsgLog (PRI_HIGH, "sshUtilsInit failed - exiting"); } radTimerDelete (sshWork.timer); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } else { sshWork.sshId = &sshWork.sshData; } if (statusInit(sshWork.statusFile, sshStatusLabels) == ERROR) { radMsgLog (PRI_HIGH, "statusInit failed - exiting..."); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (1); } statusUpdate(STATUS_BOOTING); statusUpdateStat(SSH_STATS_RULES_DEFINED, radListGetNumberOfNodes(&sshWork.sshData.rules)); // ... start THE timer ntime = time (NULL); localtime_r (&ntime, &locTime); seconds = locTime.tm_sec - 15; // start at 15 secs past /* ... start the ssh timer to go off 1 min past the next archive record */ offset = locTime.tm_min % 5; if (offset) offset = 6 - offset; else offset = 1; if (seconds < -60) { offset += 1; offset += 60; } radMsgLog (PRI_HIGH, "SSH: starting updates in %d mins %d secs", ((seconds > 0) ? ((offset > 0) ? offset-1 : offset) : offset), (seconds > 0) ? 60 - seconds : (-1) * seconds); msOffset = radTimeGetMSSinceEpoch () % 1000; msOffset -= 250; // land on 250 ms mark sshWork.msOffset = 0; radProcessTimerStart (sshWork.timer, ((((offset * 60) - seconds) * 1000)) - msOffset); statusUpdate(STATUS_RUNNING); statusUpdateMessage("Normal operation"); while (!sshWork.exiting) { /* ... wait on timers, events, file descriptors, msgs, everything! */ if (radProcessWait (0) == ERROR) { sshWork.exiting = TRUE; } } statusUpdateMessage("exiting normally"); radMsgLog (PRI_STATUS, "exiting normally..."); statusUpdate(STATUS_SHUTDOWN); if (sshWork.sshId != NULL) { sshUtilsExit (sshWork.sshId); } radTimerDelete (sshWork.timer); sshSysExit (&sshWork); radProcessExit (); radSystemExit (WVIEW_SYSTEM_ID); exit (0); }
int htmlmgrGenerate ( HTML_MGR_ID id ) { register HTML_IMG *img; int retVal, imgs = 0, htmls = 0; char temp[256]; struct stat fileData; GenerateTime = radTimeGetMSSinceEpoch (); #if __DEBUG_BUFFERS radMsgLog (PRI_STATUS, "DBG BFRS: HTML BEGIN: %u of %u available", buffersGetAvailable (), buffersGetTotal ()); #endif // ... compute the Barometric Pressure trend computeBPTrend (id); #if DEBUG_GENERATION radMsgLog (PRI_MEDIUM, "GENERATE: images"); #endif // ... generate the weather images for (img = (HTML_IMG *)radListGetFirst (&id->imgList); img != NULL; img = (HTML_IMG *)radListGetNext (&id->imgList, (NODE_PTR)img)) { retVal = (*img->generator) (img); if (retVal == OK) { imgs ++; } else if (retVal != ERROR_ABORT) { sprintf (temp, "%s/%s", id->imagePath, img->fname); radMsgLog (PRI_HIGH, "%s generation failed - must be local to the wview server!", temp); radMsgLog (PRI_HIGH, "Otherwise you may be including data in " "images.conf for which you do not have sensors?!?"); } } // ... clear the archiveAvailable flag (must be after generator loop) id->newArchiveMask = 0; #if DEBUG_GENERATION radMsgLog (PRI_MEDIUM, "GENERATE: pre-generate script"); #endif // If the wview pre-generation script exists, run it now sprintf (temp, "%s/%s", WVIEW_CONFIG_DIR, HTML_PRE_GEN_SCRIPT); if (stat (temp, &fileData) == 0) { // File exists, run it radStartProcess (newProcessEntryPoint, temp); } #if DEBUG_GENERATION radMsgLog (PRI_MEDIUM, "GENERATE: templates"); #endif // ... now generate the HTML if ((htmls = htmlgenOutputFiles(id, GenerateTime)) == ERROR) { return ERROR; } wvutilsLogEvent(PRI_STATUS, "Generated: %u ms: %d images, %d template files", (uint32_t)(radTimeGetMSSinceEpoch() - GenerateTime), imgs, htmls); id->imagesGenerated += imgs; id->templatesGenerated += htmls; statusUpdateStat(HTML_STATS_IMAGES_GENERATED, id->imagesGenerated); statusUpdateStat(HTML_STATS_TEMPLATES_GENERATED, id->templatesGenerated); #if __DEBUG_BUFFERS radMsgLog (PRI_STATUS, "DBG BFRS: HTML END: %u of %u available", buffersGetAvailable (), buffersGetTotal ()); #endif #if DEBUG_GENERATION radMsgLog (PRI_MEDIUM, "GENERATE: post-generate script"); #endif // Finally, if the wview post-generation script exists, run it now sprintf (temp, "%s/%s", WVIEW_CONFIG_DIR, HTML_POST_GEN_SCRIPT); if (stat (temp, &fileData) == 0) { // File exists, run it radStartProcess (newProcessEntryPoint, temp); } #if DEBUG_GENERATION radMsgLog (PRI_MEDIUM, "GENERATE: DONE"); #endif return OK; }