avr-evtd-1.7.7/0000755000175000017500000000000011375374431012652 5ustar rbritorbritoavr-evtd-1.7.7/avr-evtd.c0000644000175000017500000011046211375374366014561 0ustar rbritorbrito/* * Linkstation AVR daemon * * Copyright © 2006 Bob Perry * Copyright © 2008-2010 Rogério Brito * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* A few defs for later */ #define HOLD_TIME 1 #define HOLD_SECONDS 3 #define FIVE_MINUTES 5*60 #define TWELVEHR 12*60 #define TWENTYFOURHR TWELVEHR*2 #define TIMER_RESOLUTION 4095 #define FAN_SEIZE_TIME 30 #define EM_MODE_TIME 20 #define SP_MONITOR_TIME 10 /* Event message definitions */ #define SPECIAL_RESET '0' #define AVR_HALT '1' #define TIMED_SHUTDOWN '2' #define POWER_RELEASE '3' #define POWER_PRESS '4' #define RESET_RELEASE '5' #define RESET_PRESS '6' #define USER_POWER_DOWN '7' #define USER_RESET '8' #define DISK_FULL '9' #define FAN_FAULT 'F' #define EM_MODE 'E' #define FIVE_SHUTDOWN 'S' #define ERRORED 'D' /* Macro event object definition */ typedef struct _OFF_TIMER { int day; /* Event day */ long time; /* Event time (24hr) */ void *pointer; /* Pointer to next event */ } TIMER; /* Some global variables */ #ifdef MIPS static char avr_device[] = "/dev/ttyS0"; #else static char avr_device[] = "/dev/ttyS1"; #endif char config_file_location[] = "/etc/default/avr-evtd"; TIMER *offTimer = NULL; TIMER *onTimer = NULL; int FileDescriptor = 0; time_t LastMelcoAccess = 0; int TimerFlag = 0; long ShutdownTimer = 9999; /* Careful here */ char FirstTimeFlag = 1; char FirstWarning = 1; long OffTime = -1; /* Default, NO defaults */ long OnTime = -1; /* Default, NO defaults */ #ifndef NO_MELCO char CommandLineUpdate = 0; #else char CommandLineUpdate = 1; #endif int checkPercentage = 90; int last_day; int refreshRate = 40; int holdCycle = 3; char debug = 0; char pesterMessage = 0; int fanFaultSeize = 30; int checkState = 1; /* Will force an update within 15 * seconds of starting up to resolve * those pushed out refresh times */ char em_mode = 0; const char version[] = "Linkstation/Kuro AVR daemon $Rev: 147 $\n"; char rootPartition[10] = ""; /* Default, no defaults for both root * and working partitions */ char workingPartition[10] = ""; int diskCheckNumber = 0; char keepAlive = 0x5B; char resetPresses = 0; int diskUsed = 0; /* Declarations */ static void usage(void); static int check_timer(char type); static void termination_handler(int signum); static int open_serial(char *device) __attribute__ ((always_inline)); #ifdef MIPS # ifndef NO_MELCO static void parse_mips(char *buff) __attribute__ ((always_inline)); # endif #else # ifndef NO_MELCO static void parse_timer(char *buff); # endif #endif static int close_serial(void); static void avr_evtd_main(void); static char check_disk(void) __attribute__ ((always_inline)); static void set_avr_timer(char type); static void parse_avr(char *buff); static void GetTime(long timeNow, TIMER * pTimerLocate, long *time, long defaultTime); static int FindNextToday(long timeNow, TIMER * pTimer, long *time); static int FindNextDay(long timeNow, TIMER * pTimer, long *time, long *offset); static void destroyObject(TIMER * pTimer); static void writeUART(char); static void errorReport(int errorNumber); static void execute_command1(char cmd); static void execute_command(char cmd, int cmd2); static void usage(void) { printf("Usage: avr-evtd [OPTION...]\n" #ifndef MIPS " -d DEVICE listen for events on DEVICE\n" " -i display memory location for device used with -d\n" #endif " -c run in the foreground, not as a daemon\n" " -v display program version\n" " -h display this usage notice\n"); exit(0); } /* Handle ALL UART messages from a central point, reduce code overhead */ static void writeUART(char output_) { char output[4]; output[0] = output[1] = output[2] = output[3] = output_; write(FileDescriptor, output, 4); } /* Establish connection to serial port and initialise it */ static int open_serial(char *device) { struct termios newtio; #ifndef MIPS struct serial_struct serinfo; #endif /* Need read/write access to the AVR */ FileDescriptor = open(device, O_RDWR | O_NOCTTY); if (FileDescriptor < 0) { perror(device); return -1; } #ifndef MIPS /* Requested device memory address? */ if (2 == debug) { ioctl(FileDescriptor, TIOCGSERIAL, &serinfo); if (serinfo.iomem_base) printf("%p\n", serinfo.iomem_base); else printf("%X\n", serinfo.port); return 0; } #endif ioctl(FileDescriptor, TCFLSH, 2); /* Clear data structures */ memset(&newtio, 0, sizeof(newtio)); newtio.c_iflag = PARMRK; newtio.c_oflag = OPOST; #ifdef MIPS newtio.c_cflag = 0x9FD; /* CREAD | CS7 | B9600 */ #else newtio.c_cflag = PARENB | CLOCAL | CREAD | CSTOPB | CS8 | B9600; #endif /* Update tty settings */ ioctl(FileDescriptor, TCSETS, &newtio); ioctl(FileDescriptor, TCFLSH, 2); /* Initialise the AVR device this includes clearing down memory * and reseting the timer */ writeUART(0x41); writeUART(0x46); writeUART(0x4A); writeUART(0x3E); /* Remove flashing DISK LED */ writeUART(0x58); return 0; } static int close_serial(void) { if (FileDescriptor != 0) { /* The AVR does not really need to see this, just stops * the timer watchdog which happens when it powers down * anyway */ #ifndef MIPS writeUART(0x4B); #endif /* Close port and invalidate our pointer */ close(FileDescriptor); FileDescriptor = 0; } /* Destroy the macro timer objects */ destroyObject(offTimer); destroyObject(onTimer); /* Tidy up please */ closelog(); return 0; } static void termination_handler(int signum) { switch (signum) { case SIGTERM: close_serial(); exit(0); break; case SIGCONT: break; default: break; } } /* Execute event script handler with the appropriate commands */ static void execute_command(char cmd, int cmd2) { char strEventScript[45]; sprintf(strEventScript, "/etc/avr-evtd/EventScript %c %s %d &", cmd, avr_device, cmd2); system(strEventScript); } static void execute_command1(char cmd) { execute_command(cmd, 0); } /* Our main entry, decode requests and monitor activity */ static void avr_evtd_main(void) { char buf[17]; char cmd; char PushedPowerFlag = 0; char PushedResetFlag = 0; char PressedPowerFlag = 0; char PressedResetFlag = 0; char currentStatus = 0; time_t tt_TimeIdle = time(NULL); time_t tt_Power_Press = tt_TimeIdle; time_t tt_fault_time; time_t tt_LastShutdownPing; time_t tt_TimeNow; fd_set fReadFS; struct timeval tt_TimeoutPoll; int iResult; int fan_fault = 0; long lTimerDiff; char extraTime = 0; char diskFull = 0; /* Update the shutdown timer */ tt_fault_time = 0; tt_LastShutdownPing = time(NULL); /* Loop whilst port is valid */ while (FileDescriptor) { tt_TimeoutPoll.tv_usec = 0; iResult = refreshRate; /* After file change or startup, update the time within * 20 secs as the user may have pushed the refresh time * out */ if (checkState > 0) { iResult = 2; } else { /* Change our timer to check for a power/reset * request need a faster poll rate here to see * the double press event properly */ if (PushedPowerFlag || PushedResetFlag || FirstTimeFlag > 1) { tt_TimeoutPoll.tv_usec = 250; iResult = 0; checkState = -2; /* Hold off any configuration file updates */ } } if (checkState != -2) { /* Ensure we shutdown on the nail if the timer * is enabled will be off slightly as timer * reads are different */ if (1 == TimerFlag) { if (ShutdownTimer < iResult) iResult = ShutdownTimer; } /* If we have a fan failure report, then ping * frequently */ if (fan_fault > 0) iResult = fan_fault == 6 ? fanFaultSeize : 2; } tt_TimeoutPoll.tv_sec = iResult; FD_ZERO(&fReadFS); FD_SET(FileDescriptor, &fReadFS); /* Wait for AVR message or time-out? */ iResult = select(FileDescriptor + 1, &fReadFS, NULL, NULL, &tt_TimeoutPoll); tt_TimeNow = time(NULL); /* catch input? */ if (iResult > 0) { /* Read AVR message */ iResult = read(FileDescriptor, buf, 16); /* AVR command detected so force to ping only */ checkState = -2; switch (buf[0]) { /* power button release */ case 0x20: if (0 == PressedPowerFlag) { cmd = POWER_RELEASE; if ((tt_TimeNow - tt_Power_Press) <= HOLD_TIME && FirstTimeFlag < 2) { cmd = USER_RESET; } else if (ShutdownTimer < FIVE_MINUTES || FirstTimeFlag > 1) { if (0 == FirstTimeFlag) FirstTimeFlag = 10; ShutdownTimer += FIVE_MINUTES; FirstTimeFlag--; extraTime = 1; } execute_command1(cmd); tt_Power_Press = tt_TimeNow; } PushedPowerFlag = PressedPowerFlag = 0; break; /* power button push */ case 0x21: execute_command1(POWER_PRESS); PressedPowerFlag = 0; PushedPowerFlag = 1; break; /* reset button release */ case 0x22: if (0 == PressedResetFlag) { cmd = RESET_RELEASE; iResult = 0; /* Launch our telnet daemon */ if ((tt_TimeNow - tt_Power_Press) <= HOLD_TIME) { cmd = SPECIAL_RESET; iResult = resetPresses; resetPresses++; } execute_command(cmd, iResult); tt_Power_Press = tt_TimeNow; } PushedResetFlag = PressedResetFlag = 0; break; /* reset button push */ case 0x23: execute_command1(RESET_PRESS); PressedResetFlag = 0; PushedResetFlag = 1; break; /* Fan on high speed */ case 0x24: fan_fault = 6; tt_fault_time = tt_TimeNow; break; /* Fan fault */ case 0x25: /* Flag the EventScript */ execute_command(FAN_FAULT, fan_fault); if (fanFaultSeize > 0) { fan_fault = 2; tt_fault_time = tt_TimeNow; } else fan_fault = -1; break; /* Acknowledge */ case 0x30: break; /* AVR halt requested */ case 0x31: close_serial(); execute_command1(AVR_HALT); break; /* AVR initialisation complete */ case 0x33: break; #ifdef DEBUG default: if (buf[0] != 0) syslog(LOG_INFO, "unknown message %X[%d]", buf[0], iResult); break; #endif } /* Get time for use later */ time(&tt_TimeIdle); } else { /* Time-out event */ /* Check if button(s) are still held after * holdcyle seconds */ if ((tt_TimeIdle + holdCycle) < tt_TimeNow) { /* Power down selected */ if (1 == PushedPowerFlag) { /* Re-validate our time wake-up; * do not perform if in extra * time */ if (!extraTime) set_avr_timer(1); execute_command1(USER_POWER_DOWN); PushedPowerFlag = 0; PressedPowerFlag = 1; } } #ifndef UBOOT /* Has user held the reset button long enough to * request EM-Mode? */ if ((tt_TimeIdle + EM_MODE_TIME) < tt_TimeNow) { if (1 == PushedResetFlag && em_mode) { /* Send EM-Mode request to * script. The script handles * the flash device decoding and * writes the HDD no-good flag * NGNGNG into the flash status. * It then flags a reboot which * causes the box to boot from * ram-disk backup to recover * the HDD */ execute_command1(EM_MODE); PushedResetFlag = 0; PressedResetFlag = 1; } } #endif /* Skip this processing during power/reset scan */ if (!PushedResetFlag && !PushedPowerFlag && FirstTimeFlag < 2) { /* shutdown timer event? */ if (1 == TimerFlag) { /* Decrement our powerdown timer */ if (ShutdownTimer > 0) { lTimerDiff = (tt_TimeNow - tt_LastShutdownPing); /* If time difference is more than a minute, * force a re-calculation of shutdown time */ if (refreshRate + 60 > abs(lTimerDiff)) { ShutdownTimer -= lTimerDiff; /* Within five * minutes of * shutdown? */ if (ShutdownTimer < FIVE_MINUTES) { if (FirstTimeFlag) { FirstTimeFlag = 0; /* Inform the EventScript */ execute_command(FIVE_SHUTDOWN, ShutdownTimer); /* Re-validate out time wake-up; do not perform if in extra time */ if (!extraTime) set_avr_timer(1); } } } /* Large clock drift, * either user set time * or an ntp update, * handle * accordingly. */ else { check_timer(2); } } else { /* Prevent re-entry and * execute command */ PushedPowerFlag = PressedResetFlag = 2; execute_command1(TIMED_SHUTDOWN); } } /* Keep track of shutdown time remaining */ tt_LastShutdownPing = time(NULL); /* Split loading, handle disk checks * over a number of cycles, reduce CPU hog */ switch (checkState) { /* Kick state machine */ case 0: checkState = 1; break; /* Check for timer change * through configuration file */ case 1: check_timer(0); checkState = 2; break; /* Check the disk and ping AVR accordingly */ case -2: /* Check the disk to see if full * and output appropriate AVR * command? */ case 2: cmd = keepAlive; if ((currentStatus = check_disk())) { /* Execute some user code on disk full */ if (FirstWarning) { FirstWarning = pesterMessage; execute_command (DISK_FULL, diskUsed); } } /* Only update DISK LED on disk full change */ if (diskFull != currentStatus) { /* LED status */ cmd = 0x56; if (currentStatus) cmd++; else { FirstWarning = 0; execute_command (DISK_FULL, 0); } diskFull = currentStatus; } /* Ping AVR */ writeUART(cmd); checkState = 3; break; /* Wait for next refresh kick */ case 3: checkState = 0; break; } } /* Try and catch spurious fan fault messages */ switch (fan_fault) { case -1: break; case 1: fan_fault = 0; break; /* Check how long we have been operating with a fan failure */ case 2: case 3: case 4: if ((tt_fault_time + fanFaultSeize) < tt_TimeNow) { /* Run some user script on no * fan restart message after * FAN_FAULT_SEIZE time */ execute_command(FAN_FAULT, 4); fan_fault = 5; } break; /* Fan sped up message received */ case 6: /* Attempt to slow fan down again after 5 minutes */ if ((tt_fault_time + FIVE_MINUTES) < tt_TimeNow) { writeUART(0x5C); fan_fault = 1; } break; } /* Check that the shutdown pause function (if * activated) is still available, no then ping * the delayed time */ if ((tt_Power_Press + SP_MONITOR_TIME) < tt_TimeNow && FirstTimeFlag > 1) { /* Inform the EventScript */ execute_command(FIVE_SHUTDOWN, (int) ((float) ShutdownTimer / 60.0f)); FirstTimeFlag = 1; tt_Power_Press = 0; } } } } int main(int argc, char *argv[]) { char *thisarg; argc--; argv++; /* Parse any options */ while (argc >= 1 && '-' == **argv) { thisarg = *argv; thisarg++; switch (*thisarg) { #ifndef MIPS case 'd': --argc; argv++; sprintf(avr_device, "%s", *argv); break; case 'i': --argc; debug = 2; break; #endif case 'c': --argc; debug = 1; break; case 'v': --argc; printf("%s", version); exit(0); case 'e': --argc; em_mode = 1; break; case 'h': usage(); exit(0); default: usage(); } argc--; argv++; } if (!debug) { /* Run in background? */ if (daemon(0, 0) != 0) { exit(-1); } } else if (1 == debug) check_timer(0); /* Set up termination handlers */ signal(SIGTSTP, SIG_IGN); /* ignore tty signals */ signal(SIGHUP, SIG_IGN); signal(SIGCHLD, SIG_IGN); signal(SIGTERM, termination_handler); signal(SIGCONT, termination_handler); signal(SIGINT, termination_handler); /* Specified port? */ if (open_serial(avr_device)) { exit(-3); } #ifndef MIPS if (debug > 1) { close(FileDescriptor); exit(0); } #endif /* make child session leader */ setsid(); /* clear file creation mask */ umask(0); /* Open logger for this daemon */ openlog("avr-daemon", LOG_PID | LOG_NOWAIT | LOG_CONS, LOG_WARNING); syslog(LOG_INFO, "%s", version); /* Our main */ avr_evtd_main(); return 0; } static void errorReport(int errorNumber) { execute_command(ERRORED, errorNumber); } static char check_disk(void) { /* Check that the filesystem is intact and we have at least * DISKCHECK% spare capacity NOTE: DISK FULL LED may flash * during a disk check as /dev/hda3 mount check will not be * available, this is not an error and light will extinguish * once volume has been located */ static char FirstTime = 0; static char strRoot[16]; static char strWorking[16]; struct statfs mountfs; char bFull = 0; int errno; int total = 0; int total2 = 0; char cmd; char *pos; int file; int iRead; int i; char buff[4096]; /* First time then determine paths */ if (FirstTime < diskCheckNumber) { FirstTime = 0; /* Get list of mounted devices */ file = open("/etc/mtab", O_RDONLY); /* Read in the mounted devices */ if (file) { iRead = read(file, buff, 4095); pos = strtok(buff, " \n"); if (iRead > 0) { for (i = 0; i < 60; i++) { cmd = -1; if (strcasecmp(pos, rootPartition) == 0) cmd = 0; else if (strcasecmp (pos, workingPartition) == 0) cmd = 1; pos = strtok(NULL, " \n"); if (!pos) break; /* Increment firsttime check, * with bad restarts, /dev/hda3 * may not be mounted yet * (running a disk check) */ switch (cmd) { case 0: sprintf(strRoot, "%s", pos); FirstTime++; break; case 1: sprintf(strWorking, "%s", pos); FirstTime++; break; } } } } close(file); } /* Only perform these tests if DISKCHECK is enabled and * partition's havev been defined */ if (checkPercentage > 0 && diskCheckNumber > 0) { errno = -1; /* Ensure root and/or working paths have been located */ if (diskCheckNumber == FirstTime) { /* Check mount directory */ if (strlen(strRoot) > 0) { errno = statfs(strRoot, &mountfs); /* This is okay for ext2/3 but may not * be correct for other formats */ if (0 == errno) { total = 100 - (int) ((((double) mountfs. f_bavail / (double) mountfs.f_blocks) * 100.0f) + 0.99); if (total >= checkPercentage) bFull = 1; } } if (strlen(strWorking) > 0) { /* Check root */ errno = statfs(strWorking, &mountfs); if (0 == errno) { total2 = 100 - (int) ((((double) mountfs.f_bavail / (double) mountfs.f_blocks) * 100.0f) + 0.99); if (total2 >= checkPercentage) bFull = 1; } } } /* Ensure device is mounted */ if (0 != errno) { /* Indicate the /mnt is not available */ writeUART(0x59); } } diskUsed = total2; if (total > total2) diskUsed = total; return bFull; } #ifndef NO_MELCO #ifndef MIPS static void parse_timer(char *buff) { /* Parse our time requests */ int offHour, offMinutes, onHour, onMinutes; long offTime = -1, onTime = -1; /* Parse the data for breakdown later */ if (sscanf (buff, "on<>%02d:%02d<>%02d:%02d", &offHour, &offMinutes, &onHour, &onMinutes)) { TimerFlag = 1; offTime = (offHour * 60) + offMinutes; onTime = (onHour * 60) + onMinutes; } else if (sscanf (buff, "off<>%02d:%02d<>%02d:%02d", &offHour, &offMinutes, &onHour, &onMinutes)) { TimerFlag = 0; } else { TimerFlag = 0; } if (1 == TimerFlag) { OffTime = offTime; OnTime = onTime; } } #endif #endif /* Parse configuration file /etc/default/avr-evtd */ static void parse_avr(char *buff) { const char *command[] = { "TIMER", "SHUTDOWN", "OFF", "POWERON", "ON", "DISKCHECK", "REFRESH", "HOLD", "SUN", "MON", "TUE", "WED", "THR", "FRI", "SAT", "DISKNAG", "FANSTOP", "ROOT", "WORK" }; char *pos; char *last; /* Used by strtok_r to point to current token */ int i, j; int cmd; int iHour; int iMinutes; int iGroup = 0; int ilastGroup = 0; int iFirstDay = -1; int iProcessDay = -1; TIMER *pTimer; TIMER *pOff; TIMER *pOn; /* Parse our time requests */ pos = strtok_r(buff, ",=\n", &last); /* Destroy the macro timer objects, if any */ destroyObject(offTimer); destroyObject(onTimer); /* Now create our timer objects for on and off events */ pOn = onTimer = calloc(sizeof(TIMER), sizeof(char)); pOff = offTimer = calloc(sizeof(TIMER), sizeof(char)); /* Establish some defaults */ pesterMessage = 0; TimerFlag = 0; refreshRate = 40; holdCycle = 3; diskCheckNumber = 0; /* To prevent looping */ for (i = 0; i < 200; i++) { cmd = -1; /* Ignore comment lines? */ if ('#' != pos[0]) { /* Could return groups, say MON-THR, need to * strip '-' out */ if ('-' == pos[3]) { *(last - 1) = (char) '='; /* Plug the '0' with token parameter */ iGroup = 1; last -= 8; pos = strtok_r(NULL, "-", &last); } /* Locate our expected commands */ for (cmd = 0; cmd < 19; cmd++) if (strcasecmp(pos, command[cmd]) == 0) break; pos = strtok_r(NULL, ",=\n", &last); } else { pos = strtok_r(NULL, "\n", &last); /* After the first remark we have ignored, make * sure we detect a valid line and move the * tokeniser pointer if none remark field */ if ('#' != pos[0]) { j = strlen(pos); *(last - 1) = (char) ','; /* Plug the '0' with token parameter */ last = last - (j + 1); /* Now lets tokenise this valid line */ pos = strtok_r(NULL, ",=\n", &last); } } if (!pos) break; if ('#' == pos[0]) cmd = -1; /* Now parse the setting */ /* Excuse the goto coding, not nice but necessary here */ switch (cmd) { /* Timer on/off? */ case 0: if (strcasecmp(pos, "ON") == 0) TimerFlag = 1; break; /* Shutdown? */ case 1: pTimer = pOff; iHour = iMinutes = -1; goto process; /* Macro OFF? */ case 2: pTimer = pOff; iHour = 24; iMinutes = 0; goto process; /* Power-on? */ case 3: pTimer = pOn; iHour = iMinutes = -1; goto process; /* Macro ON? */ case 4: pTimer = pOn; iHour = iMinutes = 0; process: if (!sscanf(pos, "%02d:%02d", &iHour, &iMinutes)) TimerFlag = -1; /* Ensure time entry is valid */ else if ((iHour >= 0 && iHour <= 24) && (iMinutes >= 0 && iMinutes <= 59)) { /* Valid macro'd OFF/ON entry? */ if (2 == cmd || 4 == cmd) { /* Group macro so create the other events */ if (iGroup != 0) { j = iFirstDay - 1; /* Create the multiple * entries for each day * in range specified */ while (j != iProcessDay) { j++; if (j > 7) j = 0; pTimer->day = j; pTimer->time = (iHour * 60) + iMinutes; /* Allocate * space for the * next event * object */ pTimer->pointer = (void *) calloc(sizeof (TIMER), sizeof (char)); pTimer = (TIMER *) pTimer-> pointer; } } else { pTimer->day = iProcessDay; pTimer->time = (iHour * 60) + iMinutes; /* Allocate space for the next event object */ pTimer->pointer = (void *) calloc(sizeof(TIMER), sizeof(char)); pTimer = (TIMER *) pTimer->pointer; } } /* Now handle the defaults */ else if (1 == cmd) OffTime = (iHour * 60) + iMinutes; else if (3 == cmd) OnTime = (iHour * 60) + iMinutes; } else TimerFlag = -1; /* Update our pointers */ if (cmd < 3) pOff = pTimer; else pOn = pTimer; break; /* Disk check percentage? */ case 5: if (!sscanf(pos, "%d", &checkPercentage)) checkPercentage = -1; /* Ensure valid percentage range */ else if (checkPercentage > 100) checkPercentage = 100; else if (checkPercentage < 0) checkPercentage = -1; break; /* Refresh/re-scan time? */ case 6: if (sscanf(pos, "%03d", &refreshRate)) refreshRate = 40; /* Limit to something sensible */ else if (refreshRate > FIVE_MINUTES) refreshRate = FIVE_MINUTES; else if (refreshRate < 10) refreshRate = 1; break; /* Button hold-in time? */ case 7: if (sscanf(pos, "%02d", &holdCycle)) holdCycle = HOLD_SECONDS; /* Limit to something sensible */ else if (holdCycle > 10) holdCycle = 10; else if (holdCycle < 2) holdCycle = 2; break; /* Macro days in week? */ case 8: case 9: case 10: case 11: case 12: case 13: case 14: /* For groups, */ iProcessDay = cmd - 8; /* Remove grouping flag for next defintion */ ilastGroup += iGroup; if (ilastGroup > 2) { iGroup = 0; ilastGroup = 0; } if (1 == ilastGroup) iFirstDay = iProcessDay; break; case 15: if (strcasecmp(pos, "ON") == 0) pesterMessage = 1; /* Fan failure stop time before event trigger */ case 16: if (strcasecmp(pos, "OFF") == 0) fanFaultSeize = 0; else { if (sscanf(pos, "%02d", &fanFaultSeize)) fanFaultSeize = FAN_SEIZE_TIME; /* Limit to something sensible */ else if (fanFaultSeize > 60) fanFaultSeize = 60; else if (fanFaultSeize < 1) fanFaultSeize = 1; } break; break; /* Specified partiton names */ case 17: case 18: if (strlen(pos) <= 5) { diskCheckNumber++; /* Specified ROOT partiton */ if (17 == cmd) sprintf(rootPartition, "/dev/%s", pos); else /* Specified WORKING partiton */ sprintf(workingPartition, "/dev/%s", pos); } break; } } if (TimerFlag < 0) { TimerFlag = 0; errorReport(3); } } static void destroyObject(TIMER * pTimer) { /* Destroy this object by free-ing up the memory we grabbed * through calloc */ TIMER *pObj; /* Ensure valid pointer */ if (pTimer) { /* Bad this, can loop but let's destroy and free our * objects */ for (;;) { pObj = pTimer->pointer; if (NULL == pObj) break; free(pTimer); pTimer = NULL; pTimer = pObj; } pTimer = NULL; } } static int FindNextToday(long timeNow, TIMER * pTimer, long *time) { /* Scan macro objects for a valid event from 'time' today */ int iLocated = 0; while (pTimer != NULL && pTimer->pointer != NULL) { /* Next event for today?, at least 1 minute past current */ if (pTimer->day == last_day && pTimer->time > timeNow) { iLocated = 1; *time = pTimer->time; pTimer = NULL; } else { pTimer = pTimer->pointer; } } return iLocated; } static int FindNextDay(long timeNow, TIMER * pTimer, long *time, long *offset) { /* Locate the next valid event */ int iLocated = 0; while (pTimer != NULL && pTimer->pointer != NULL) { /* Next event for tomorrow onwards? */ if (pTimer->day > last_day) { /* Grouped events?, ie only tomorrow */ if (pTimer->day > last_day) *offset = (pTimer->day - last_day) * TWENTYFOURHR; iLocated = 1; *time = pTimer->time; pTimer = NULL; } else { pTimer = pTimer->pointer; } } return iLocated; } static void GetTime(long timeNow, TIMER * pTimerLocate, long *time, long defaultTime) { /* Get next timed macro event */ long lOffset = 0; char onLocated = 0; TIMER *pTimer; /* Ensure that macro timer object is valid */ if (pTimerLocate && pTimerLocate->pointer != NULL) { lOffset = 0; pTimer = pTimerLocate; /* Next event for today */ onLocated = FindNextToday(timeNow, pTimer, time); /* Failed to find a time for today, look for the next * power-up time */ if (0 == onLocated) { pTimer = pTimerLocate; onLocated = FindNextDay(timeNow, pTimer, time, &lOffset); } /* Nothing for week-end, look at start */ if (0 == onLocated) { *time = pTimerLocate->time; lOffset = ((6 - last_day) + pTimerLocate->day) * TWENTYFOURHR; } *time += lOffset; if (lOffset > TWENTYFOURHR && defaultTime > 0) *time = defaultTime; } else *time = defaultTime; } #ifndef NO_MELCO #ifdef MIPS static void parse_mips(char *buff) { /* type=off backup_status=off backup_time=0:00 backup_type=day backup_week=Sun backup_overwrite=off sleep_start=0:00 sleep_finish=9:00 */ const char *command[] = { "type", "backup_time", "sleep_start", "sleep_finish" }; char *pos; int i; int cmd = 0; int backupHour, backupMinutes, offHour, offMinutes, onHour, onMinutes; long offTime, onTime; TimerFlag = 0; /* Parse our time requests */ pos = strtok(buff, "=\n"); /* Parse the data for breakdown later */ for (i = 0; i < 16; i++) { cmd = -1; /* Locate our expected commands */ for (cmd = 0; cmd < 4; cmd++) if (strcasecmp(pos, command[cmd]) == 0) break; pos = strtok(NULL, "=\n"); if (!pos) break; /* Now parse the setting type is sleep otherwise deemed off backup_time expects HH:MM NOT CURRENTLY SUPPORTED sleep_start expects HH:MM if not, then timer is disabled sleep_finish expects HH:MM if not, then timer is disabled */ switch (cmd) { case 0: if (strcasecmp(pos, "sleep") == 0) TimerFlag = 1; break; case 1: sscanf(pos, "%02d:%02d", &backupHour, &backupMinutes); break; case 2: if (!sscanf (pos, "%02d:%02d", &offHour, &offMinutes)) TimerFlag = -1; break; case 3: if (!sscanf(pos, "%02d:%02d", &onHour, &onMinutes)) TimerFlag = -1; break; } } /* Failed timer needs timer=sleep and both off time and on time * to be specified */ if (1 == TimerFlag) { offTime = (offHour * 60) + offMinutes; onTime = (onHour * 60) + onMinutes; OffTime = offTime; OnTime = onTime; } else if (TimerFlag != 0) { TimerFlag = 0; errorReport(4); } } #endif #endif static void set_avr_timer(char type) { /* Determine shutdown/power up time and fire relevant string * update to the AVR */ const char *strMessage[] = { "file update", "re-validation", "clock skew" }; long current_time, wait_time; time_t ltime, ttime; struct tm *decode_time; char message[80]; char strAVR; char twelve; int i; long mask = 0x800; long offTime, onTime; /* Timer enabled? */ if (TimerFlag) { /* Get time of day */ time(<ime); decode_time = localtime(<ime); current_time = (decode_time->tm_hour * 60) + decode_time->tm_min; last_day = decode_time->tm_wday; GetTime(current_time, offTimer, &offTime, OffTime); /* Correct search if switch-off is tommorrow */ if (offTime > TWENTYFOURHR) GetTime(current_time, onTimer, &onTime, OnTime); else GetTime(offTime, onTimer, &onTime, OnTime); /* Protect for tomorrows setting */ twelve = 0; if (offTime < current_time) { twelve = 1; ShutdownTimer = ((TWELVEHR + (offTime - (current_time - TWELVEHR))) * 60); } else { ShutdownTimer = ((offTime - current_time) * 60); } /* Remeber the current seconds passed the minute */ ShutdownTimer -= decode_time->tm_sec; ttime = ltime + ShutdownTimer; decode_time = localtime(&ttime); sprintf(message, "Timer is set with %02d/%02d %02d:%02d", decode_time->tm_mon + 1, decode_time->tm_mday, decode_time->tm_hour, decode_time->tm_min); /* Now setup the AVR with the power-on time */ /* Correct to AVR oscillator */ if (onTime < current_time) { wait_time = (TWELVEHR + (onTime - (current_time - TWELVEHR))) * 60; onTime = ((TWELVEHR + (onTime - (current_time - TWELVEHR))) * 100) / 112; } else { if (onTime < (offTime - TWENTYFOURHR)) onTime += TWENTYFOURHR; else if (onTime < offTime) onTime += TWENTYFOURHR; wait_time = (onTime - current_time) * 60; onTime = ((onTime - current_time) * 100) / 112; } /* Limit max off time to next power-on to the resolution of the timer */ if (onTime > TIMER_RESOLUTION && (onTime - (ShutdownTimer / 60)) > TIMER_RESOLUTION) { wait_time -= ((onTime - TIMER_RESOLUTION) * 672) / 10; errorReport(2); /* Reset to timer resolution */ onTime = TIMER_RESOLUTION; } ttime = ltime + wait_time; decode_time = localtime(&ttime); sprintf(message, "%s-%02d/%02d %02d:%02d (Following timer %s)", message, decode_time->tm_mon + 1, decode_time->tm_mday, decode_time->tm_hour, decode_time->tm_min, strMessage[(int) type]); syslog(LOG_INFO, message); /* Now tell the AVR we are updating the 'on' time */ writeUART(0x3E); writeUART(0x3C); writeUART(0x3A); writeUART(0x38); /* Bit pattern (12-bits) detailing time to wake */ for (i = 0; i < 12; i++) { strAVR = (onTime & mask ? 0x21 : 0x20) + ((11 - i) * 2); mask >>= 1; /* Output to AVR */ writeUART(strAVR); } /* Complete output and set LED state (power) to pulse */ writeUART(0x3F); keepAlive = 0x5B; } /* Inform AVR its not in timer mode */ else { writeUART(0x3E); keepAlive = 0x5A; } writeUART(keepAlive); } static int check_timer(char type) { /* Check to see if we need to perform an update. We check the original melco timer file (timer_sleep) for timer requests if required */ int iReturn = 1; int iRead; int errno; char buff[4096]; int file; struct stat filestatus; #ifndef NO_MELCO /* Expect its a file time read required? This is purely for legacy timer files only. If this does not exist, then we look for our default */ if (0 == CommandLineUpdate) { CommandLineUpdate = 1; /* Get file status of sleep timer file */ #ifdef MIPS errno = stat("/etc/melco/timer_status", &filestatus); #else errno = stat("/etc/melco/timer_sleep", &filestatus); #endif /* If exists? */ if (0 == errno) { /* Has this file changed? */ if (filestatus.st_mtime != LastMelcoAccess) { iRead = -1; /* Open and read the contents */ #ifdef MIPS file = open("/etc/melco/timer_status", O_RDONLY); if (file) { iRead = read(file, buff, 254); /* Dump the file pointer for others */ close(file); if (iRead > 0) parse_mips(buff); } #else file = open("/etc/melco/timer_sleep", O_RDONLY); if (file) { iRead = read(file, buff, 31); /* Dump the file pointer for others */ close(file); if (iRead > 0) parse_timer(buff); } #endif if (iRead > 0) { /* Return flag */ iReturn = CommandLineUpdate = 0; set_avr_timer(type); } } else CommandLineUpdate = 0; /* Update our lasttimes timer file access */ LastMelcoAccess = filestatus.st_mtime; } else { /* standard Melco files do not exist, * back to the avr-evtd defaults */ LastMelcoAccess = 0; CommandLineUpdate = 1; } } #endif /* Time from avr-evtd configuration file */ if (1 == CommandLineUpdate) { /* File is missing so default to off and do not do this * again */ CommandLineUpdate = 2; errno = stat(config_file_location, &filestatus); /* If exists? */ if (0 == errno) { /* Has this file changed? */ if (filestatus.st_mtime != LastMelcoAccess) { file = open(config_file_location, O_RDONLY); if (file) { iRead = read(file, buff, 4095); /* Dump the file pointer for others */ close(file); if (iRead > 0) { /* Return flag */ iReturn = 0; CommandLineUpdate = 1; parse_avr(buff); set_avr_timer(type); } } } else CommandLineUpdate = 1; /* Update our lasttimes timer file access */ LastMelcoAccess = filestatus.st_mtime; } } /* Ensure that if we have any configuration errors we at least * set timer off */ if (2 == CommandLineUpdate) { CommandLineUpdate = 3; set_avr_timer(type); errorReport(1); } return iReturn; } avr-evtd-1.7.7/Install/0000755000175000017500000000000011375374431014260 5ustar rbritorbritoavr-evtd-1.7.7/Install/avr-evtd.init0000755000175000017500000000623311375374323016704 0ustar rbritorbrito#!/bin/sh # # avr-evtd Linkstation/Kuro AVR daemon # # Files used: # /etc/default/avr-evtd file with defaults for this script # /etc/avr-evtd/EventScript script with emergency mode actions # # Optional files: # /etc/melco/timer_Sleep Standard Melco sleep settings # # Copyright © 2006 Bob Perry # Copyright © 2008-2010 Rogério Brito # ### BEGIN INIT INFO # Provides: avr-evtd # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Linkstation/Kurobox AVR watchdog daemon ### END INIT INFO PATH=/bin:/sbin:/usr/bin:/usr/sbin NAME=avr-evtd DAEMON=/usr/sbin/$NAME DESC="AVR watchdog daemon" tag=linkstation facility=user.info test -x $DAEMON || exit 0 . /lib/lsb/init-functions if [ -f /etc/default/$NAME ]; then . /etc/default/$NAME fi determine_device() { # Accept the device specified by the system administrator, if set. [ ! -z "$DEVICE" ] && return # For MIPS, the situation is simpler: just use /dev/ttyS0 as the UART. # For PowerPC, we need to know which, between ttyS0 or ttyS1 is attached # to port address 0x80004500 and use that. DEVICE=/dev/ttyS0 if uname -m | grep -q mips; then MIPS=YES else MIPS=NO PORT_ADDRESS=$($DAEMON -i -d /dev/ttyS1) if [ -n "$PORT_ADDRESS" ] && [ "$PORT_ADDRESS" = "0x80004500" ]; then DEVICE=/dev/ttyS1 fi fi } start() { # Cumulative string of options to be passed to the daemon # (e.g -d /dev/ttyS1) DAEMONOPTS="" CONSOLE=OFF determine_device # Initialize according to configurations if [ "$EMMODE" = "YES" ]; then DAEMONOPTS=-e fi if [ -n "$DEVICE" ] && [ "$MIPS" = "NO" ]; then DAEMONOPTS="$DAEMONOPTS -d $DEVICE" fi # If this is a MIPSEL box, then determine if console ttyS0 is in use if [ "$MIPS" = "YES" ] && [ -e /proc/linkstation ]; then CONSOLE=$(grep CONSOLE < /proc/linkstation | cut -d = -f 2) fi if [ "$CONSOLE" = "ON" ]; then log_warning_msg "avr-evtd: Not started services as console in-use" logger -t $tag -p $facility -i "Not started avr-evtd as kernel still has console" else log_daemon_msg "Starting $DESC " "$NAME" start-stop-daemon --start --quiet --exec $DAEMON -- $DAEMONOPTS log_end_msg $? logger -t $tag -p $facility -i "Started daemon avr-evtd" fi } stop() { determine_device # Determine run-level and respond accordingly # Speed-up fan at exit for an extra chill. if [ -n "$RUNLEVEL" ] && [ -n "$DEVICE" ]; then if [ "$RUNLEVEL" -eq 6 ]; then # Send AVR the reboot signal echo -n "]]]]CCCC" > $DEVICE elif [ "$RUNLEVEL" -eq 0 ]; then # Send AVR the shutdown signal echo -n "]]]]EEEE" > $DEVICE fi fi log_daemon_msg "Stopping $DESC" "$NAME" start-stop-daemon --stop --quiet --exec $DAEMON log_end_msg $? logger -t $tag -p $facility -i 'Stopped daemon avr-evtd' } # Check request case "$1" in start) start ;; stop) stop ;; restart|force-reload) stop sleep 1 start ;; *) echo "Usage: $DAEMON {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0 avr-evtd-1.7.7/Install/emergency-eth00000755000175000017500000000043711375374323017026 0ustar rbritorbrito# EM static IP (adjust to your network settings) # iface eth0 inet static address 192.168.11.150 network 192.168.11.0 netmask 255.255.255.0 broadcast 192.168.11.255 gateway 192.168.11.254 iface eth0:AUTO inet dhcp hostname `hostname` auto eth0 eth0:AUTO avr-evtd-1.7.7/Install/recovery.tar0000644000175000017500000002400011375374323016622 0ustar rbritorbritoetc/group0000644000000000000000000000100210515233332011374 0ustar rootrootroot:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20: fax:x:21: voice:x:22: cdrom:x:24: floppy:x:25: tape:x:26: sudo:x:27: audio:x:29: dip:x:30: www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: gnats:x:41: shadow:x:42: utmp:x:43:telnetd video:x:44: sasl:x:45: plugdev:x:46: staff:x:50: games:x:60: users:x:100: nogroup:x:65534: crontab:x:101: linkstation:x:1000: ssh:x:103: telnetd:x:104: etc/gshadow0100640000000000000000000000065510515233353011711 0ustar rootrootroot:*:: daemon:*:: bin:*:: sys:*:: adm:*:: tty:*:: disk:*:: lp:*:: mail:*:: news:*:: uucp:*:: man:*:: proxy:*:: kmem:*:: dialout:*:: fax:*:: voice:*:: cdrom:*:: floppy:*:: tape:*:: sudo:*:: audio:*:: dip:*:: www-data:*:: backup:*:: operator:*:: list:*:: irc:*:: src:*:: gnats:*:: shadow:*:: utmp:*::telnetd video:*:: sasl:*:: plugdev:*:: staff:*:: games:*:: users:*:: nogroup:*:: crontab:x:: linkstation:!:: ssh:!:: telnetd:!:: etc/passwd0100644000000000000000000000154610515233337011564 0ustar rootrootroot:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh list:x:38:38:Mailing List Manager:/var/list:/bin/sh irc:x:39:39:ircd:/var/run/ircd:/bin/sh gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh linkstation:x:1000:1000:linkstation,,,:/home/linkstation:/bin/bash sshd:x:100:65534::/var/run/sshd:/bin/false telnetd:x:104:104::/nonexistent:/bin/false etc/shadow0100640000000000000000000000107610515233346011542 0ustar rootrootroot:$1$dugxGPAp$ouFuGpULedOLI6kKLqSnn0:13438:0:99999:7::: daemon:*:13028:0:99999:7::: bin:*:13028:0:99999:7::: sys:*:13028:0:99999:7::: sync:*:13028:0:99999:7::: games:*:13028:0:99999:7::: man:*:13028:0:99999:7::: lp:*:13028:0:99999:7::: mail:*:13028:0:99999:7::: news:*:13028:0:99999:7::: uucp:*:13028:0:99999:7::: proxy:*:13028:0:99999:7::: www-data:*:13028:0:99999:7::: backup:*:13028:0:99999:7::: list:*:13028:0:99999:7::: irc:*:13028:0:99999:7::: gnats:*:13028:0:99999:7::: nobody:*:13028:0:99999:7::: linkstation:$1$NocKok/f$9zur.1mvS7kmklo24yMsE.:13438:0:99999:7::: etc/issue.net0100644000000000000000000000112110515466670012175 0ustar rootroot(_______) _____ ____ _____ ____ ____ _____ ____ ____ _ _ | ___) | \| ___ |/ ___) _ | ___ | _ \ / ___) | | | | |_____| | | | ____| | ( (_| | ____| | | ( (___| |_| | |_______)_|_|_|_____)_| \___ |_____)_| |_|\____)\__ | _______ _ (_____| (____/ (_______) | | _ _ _ ___ __| |_____ Recovered Default settings | ||_|| |/ _ \ / _ | ___ | for passwd, shadow, group | | | | |_| ( (_| | ____| and gshadow. Backups made |_| |_|\___/ \____|_____) in /etc with extension .em avr-evtd-1.7.7/Install/avr-evtd.config0000644000175000017500000000236011375374323017200 0ustar rbritorbrito# Sample avr-evtd daemon configuration file # PLEASE EDIT THIS FILE TO SUIT # Debug log file location LOG=/var/log # Advanced use only. Will log events when enabled DEBUG=ON # Set to YES to enable the EM-Mode feature, default no EMMODE=NO # Timed shutdown flag (ON enables timed power down/up only # or use days of the week MONWEDSAT etc # if SHUTDOWN and POWERON are also specified) TIMER=OFF # To override the device scan, specify the desired # serial port connection to the AVR below and remove the # comment #DEVICE=/dev/ttyS1 # MACRO day/group switching ON/OFF times in 24hr HH:MM #SUN-SAT=OFF=01:15,ON=06:20 # Shutdown (default) time specified in 24hr format HH:MM #SHUTDOWN= # Power on (default) time specified in 24hr format HH:MM #POWERON= # Disk check, set to OFF or a value (0-100) specifying a # percentage used at which the disk LED will illuminate DISKCHECK=90 # Specify root partition for disk check, default is none ROOT=sda1 # Specify working partition for disk check, default is none WORK=sda3 # Disk/AVR refresh rate (seconds), default 40 REFRESH=40 # Hold time (seconds) for button power-off, default 3 HOLD=3 # Enable/disable continous disk full messages, default off DISKNAG=OFF # Fan stationary fault timer (seconds), default 30 FANSTOP=15 avr-evtd-1.7.7/Install/avr-evtd.80000644000175000017500000003455111375374323016111 0ustar rbritorbrito.TH AVR-EVTD 8 "28 Aug 2009" .SH NAME avr-evtd - Linkstation AVR Event daemon .SH SYNOPSIS avr-evtd [ .B -d .IR /dev/tty ] [i | c | v] .SH DESCRIPTION .IR avr-evtd is a simple and small user space interface to the Linkstation AVR micro-controller. It doesn't have a lot of special features, but it's main task is to provide 'keep-alive' messages to the Linkstation's on-board AVR device. This device controls/monitors the fan, various LEDs, timed power up and two buttons. This daemon provides the necessary initialization to the device and also stimulates the LEDs depending on various fault conditions. It also monitors a power button (located at the front) and a reset button (located at the rear). .IR avr-evtd searches for a configuration file located within .B /etc/melco at start-up time. If this file does not exist, then .IR avr-evtd reverts to reading the file located at .B /etc/default/avr-evtd. Additionally, .IR avr-evtd may, if requested, periodically check the root (\fBUnder user control and could be /dev/hda1\fP) partition and the user working partition (\fBFor example, /dev/hda3\fP) to ensure they are mounted. Also, if requested, it will determine if sufficient space remains and if not then the AVR is requested to illuminate the DISK LED. This periodic checking also takes place on the configuration files. If they are deemed to have been updated, then the daemon will respond accordingly. .LP Any failures are normally routed through the log files. With timed shutdown/power up, a warning will be broadcast to all users (console message) when within 5 or less minutes of power off. Also, fan failure alerts will be broadcast in this fashion. Failure to determine mounted .B working partition will result in the DIAG LED flashing three times, repeatedly. .LP A new feature of this daemon is the ability to code events for single or groups of days. This allows the user to add any number of power-on/off events as required. This also has the added benefit of being able to shut down the device for longer periods. The internal AVR timer has a 12-bit resolution timer which can power up the Linkstation from a maximum of a sixty eight hour sleep: from time of invocation. The AVR is updated again at time of power down/shutdown to re-validate the timer, in case of time updates (either by user or NTP). This will also preserve the 68 hour sleep resolution. .SH OPTIONS .TP 5 .B -d .IR /dev/tty Specifies the UART device used to communicate with the AVR. This is normally taken care of by the scripts but can be specified in the configuration file. .B See below for details. .TP 5 .B -c Don't fork, i.e. run in the foreground (debug use only). .TP .B -i Returns the port memory location for the device specified by .B -d .IR /dev/tty .TP 5 .B -v Display daemon version. .SH THE CONFIGURATION FILE The .IR avr-evtd configuration file is the fallback file in the event that the stock melco files do not exist. The file is read at initial start-up in order to determine if timed shutdown is required and if the disk usage is to be monitored. The file should be always located within the /etc/default directory and a sample file is provided. The file format is similar to other Unix configuration files - comments begin with a # character and extend to the end of the line; blank lines are ignored. Configuration commands consist of an initial keyword followed by an argument. Arguments may be strings or times written in HH:MM (UTC) format. Optional arguments are delimited by [ ] in the following descriptions, while alternatives are separated by |. .TP 5 .IR DEBUG [ON | OFF] This is reserved for admin only. Allows logging of certain information. A log file will be maintained in /etc/avr-evtd logging events and when run from command line, the process will log data to the console. .TP 5 .IR TIMER [YES | NO] The timer command informs the daemon if it has to provide time controlled shutdown and power up. If .IR TIMER is set to .B NO then this function is not available and the commands .IR SHUTDOWN and .IR POWERON are ignored and have no effect. The same applies if any day events are specified and the .IR TIMER is set to .B NO then these events will also be ignored. .TP 5 .IR DEVICE [/dev/tty] This informs the AVR which UART to use when communicating with the AVR. The communication path between the micro-controller and this daemon is via a serial link. This keyword is not for general use and is provided to allow advanced users the option of overriding automatic configuration. This would normally be set to /dev/ttyS1 but on some systems it is /dev/ttyS0. The selection of the correct port is performed by the daemon start script and is not normally required to be altered. .TP 5 .IR [ | -] [ON=HH:MM | ON= | OFF=HH:MM | OFF=] This defines events for either a single day or group of days, '-' separator. Any number of .B ON and .B OFF events can be specified and can be extended over additional lines. can be any number of days of the week specified as either SUN, MON, TUE, WED, THR, FRI, and SAT. For example: .RS 15 .B MON-WED=ON=09:00,OFF=23:00 .RE .RS 15 .B THR=ON=09:00 .RE .RS 15 .B FRI=OFF=01:00 .RE .RS 5 In this example, the first power on event is Monday at 09:00. At 23:00 the Linkstation will power down. This is repeated for Tuesday and Wednesday. On Thursday, the Linkstation will power on at 09:00 and will power off on Friday at 01:00. The unit will then remain off for Saturday and Sunday and not power up again till 09:00 on Monday. The unit is capable of sleeping for no more than 68 hours (due to the resolution of the internal timer). Again, this time MUST be specified in UTC format and follow HH:MM. .LP Five minutes before power off is required, a message is broadcast to all console users. At shutdown, an event message is sent to the event script. .B See below for more details. .RE .TP 5 .IR SHUTDOWN [HH:MM] This specifies the time that the Linkstation will be powered down. This time MUST be specified in UTC and must follow the format HH:MM. If the user alters this configuration file whilst the daemon is running, then the change will be seen and the new settings will be implemented. If the new time entered is passed the current time, then the shutdown time will be for the following day. If single or multiple day events are specified, then this becomes the default power down time for any undefined days. .TP 5 .IR POWERON [HH:MM] This specifies the time that the Linkstation will be automatically powered up; as long as now unexpected power outage occurs. Again, if this time is less than the .IR SHUTDOWN time then it is for the following day. Both the .IR TIMER set to ON and the .IR SHUTDOWN and the .IR POWERON times are valid will timed shutdown/power up be enabled. This will be reported in the message log along with any errors in the configuration file. .RS 5 If single or multiple day events are specified, then this becomes the default power on time for any undefined days. .RE .TP 5 .IR DISKCHECK [OFF | 0..100] If this is set to OFF or 0 (zero) then disk usage/monitoring is disabled. Set to a value between 0 and 100% to monitor disk usage. If disk usage is above this specified value, then the DISK LED will be illuminated. At the same time, a disk full event message will be sent to the event script. .TP 5 .IR ROOT [hda1..9] No default. This allows the root partition to be defined by the user. No syntax checking is performed on this entry or validation of the partition ID. .TP 5 .IR WORK [hda1..9] No default. This allows the working partition to be defined by the user. Again, no syntax checking is performed on this entry or validation of the partition ID. .TP 5 .IR REFRESH [1..300] This defaults to 40. This provides control over the rate (in seconds) that the daemon checks the system for changes and refreshes the AVR. Any number between 1 and 300 can be entered. Anything less than the default will result in higher impact on the system: more CPU usage. Higher times will result with slower response to configuration file changes but this may not be an issue with most users. .TP 5 .IR HOLD [1..9] This defaults to 3. This provides control over the time (in seconds) that the user needs to hold either the reset of the power button in for a reset event (reset button) or power off event (power button). .TP 5 .IR DISKNAG [ON | OFF] Default if off. This provides the user control over the disk full event. The default is that once detected, just a single event is triggered. If required, setting this to on will generate repeated events, at the frequency of .B REFRESH until the disk is no longer deemed full. .TP 5 .IR FANSTOP [OFF | 0..60] Default is 30 seconds. This is the time, from report of fan failure in which the daemon will generate a fan failure event call to the event script. This allows the user to act accordingly. At present, the script is setup to power down. This can be changed to an e-mail event prior to shutdown if required. Otherwise, if a user has decided to remove the fan then this can be set to OFF to prevent shutdown from occuring. It must be stressed that alternative cooling must be sourced if this option is selected. .SH BUTTON OPERATION All events, whether mechanical button operation, or software reset/shutdown actions are routed through an event script located at .B /etc/avr-evtd/EventSCript .TP 5 .IR POWER On press, a button event message is sent. On release, another event message is sent. If the button is held in for more than .B HOLD seconds, then a shutdown event request is sent. If the button is pressed twice within a period of one second, then a reset request event is sent. .RS 5 If the power button is pressed during the five minute timed shutdown warning, then the shutdown time is increased by five minutes. Multiple presses will keep increasing the time by five minutes (to a maximum pause of fifty minutes). This provides the user with the ability to carry on working before timed shutdown is finally activated; careful here as repeated presses maybe seen as a reboot request. .RE .TP 5 .IR RESET On press, a button event message is sent. On release, another event message is sent. If the button is held in for more than twenty seconds, then a EM-Mode event request is sent. If the button is pressed twice within a period of one second, then a .I special event is sent which in the default state will launch the telnet daemon. .SH MESSAGE EVENTS The event system has been modified such that 99% of the daemon event system is pushed through the event script. A third parameter is supplied by the daemon out to the script detailing information relevant to the generated message. For example, for a disk full message, the third parameter would detail the percentage disk space used (worst of the two monitored partitions) and when this is cleared, then this parameter would be cleared to zero. .TP 5 .IR 0 User has requested (by double press of reset button) to, with the first press, launch the telnet daemon, or other client as specified in the .IR EventScript. The script also establishes a static IP to an alias Ethernet device :EM at 192.168.11.150. If this IP is already in-use, then it will not be created. If the Ethernet is not running, then an alternative Ethernet configuration file is loaded providing a static IP at 192.168.11.150. and also a DHCP provided IP. On the .IR THIRD double press, then a known set of group and user password files are copied to /etc. Prior to the transfer, the relevant original files are copied to .IR .em. A file, recovery.tar, is extracted and the LEDs are flashed to indicate this new mode. A user can now gain root access using the password .I emergency and gain access via the telnet port 1234 to their box. .TP 5 .IR 1 AVR micro-controller has requested a reset. .TP 5 .IR 2 Shutdown request from the shutdown timer event. .TP 5 .IR 3 Power button has been released event. .TP 5 .IR 4 Power button has been pressed event. .TP 5 .IR 5 Reset button (rear of unit) has been released. .TP 5 .IR 6 Reset button has been pressed. .TP 5 .IR 7 User has requested (by holding power button for more than .B HOLD seconds) to shutdown the unit. .TP 5 .IR 8 User has requested (by double press of the power button) to reset the unit. .TP 5 .IR 9 Disk usage greater than DISKCHECK. Parameter 3 set to percentage used or zero. .TP 5 .IR F Fan has been stationary for FANSTOP seconds. Parameter 3 is set to 4 when cleared. .TP 5 .IR E EM-Mode has been selected. The EM-Mode sequence is written to the desired flash location and the system is issued a reboot request. EM-Mode is an emergency boot mode that for the Linkstation it boots from an image in flash and rebuilds files on the disk. .B This should only be used by those who know what will happen to their disks when this Mode is selected .TP 5 .IR S The system will shutdown in less than five minutes warning. Parameter 3 indicates shutdown delay on power press. .TP 5 .IR D Error message handler. Parameter 3 indicates error number. .SH ERROR CODES The following error messages maybe displayed in the log files during operation: .TP 5 .IR 1 No stock or avr-evtd configuration files were located. .TP 5 .IR 2 Power off time greater than that supported by the AVR. As this is calculated at the time the timer is established, this fault may clear at shutdown as timers are re-validated. .TP 5 .IR 3 Timer declaration error in /etc/default/avr-evtd configuration file .TP 5 .IR 4 Error in stock configuration file .SH FILES .RS 0 .IR /etc/default/avr-evtd .RE .RS 0 .IR /etc/avr-evtd/EventScript .RE .RS 0 .IR /etc/avr-evtd/emergency-eth0 .RE .RS 0 .IR /etc/default/events.log .RE .RS 0 .IR /etc/avr-evtd/recovery.tar .RE .SH AUTHORS Bob Perry (2006), with some modifications by Rog\['e]rio Brito (2008, 2009). .SH COPYRIGHT This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. .LP This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. .LP You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. avr-evtd-1.7.7/Install/COPYING0000644000175000017500000004310311375374323015314 0ustar rbritorbrito GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. avr-evtd-1.7.7/Install/EventScript0000755000175000017500000001114011375374323016451 0ustar rbritorbrito#!/bin/bash # avr-evtd Event script # # Sample Event Script written by Bob Perry # NOTE: No longer syncronous with avr-evtd process: maybe more than # one instance of this script running # # Enters via the avr-evtd daemon with the following command options: # 0 - Special event following double press of the 'red' reset button # 1 - AVR device has requested a halt due to error # 2 - Shutdown request from timed shutdown logic # 3 - User has released the power button # 4 - User has pressed the power button # 5 - User has released the 'red' reset button # 6 - User has pressed the reset button # 7 - User has held the power button > 3 seconds # 8 - User has held the reset button > 3 seconds # 9 - Disk used beyond DISKCHECK% # F - Fan failure event, fan stopped for > FANSTOP seconds # E - User selected EM-Mode # S - Five minute shutdown warning event # D - Error message handler DEVICE=$2 PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin tag=avr-daemon facility=user.info # # Populate the configured settings # if [ -f /etc/default/avr-evtd ]; then . /etc/default/avr-evtd fi if [ "$DEBUG" = "ON" ] && [ -d "$LOG" ]; then echo "`date` command is $1[$3] for $DEVICE" >> $LOG/avr-evtd.log fi case "$1" in 0) case "$3" in 1) # Indicate this mode by flashing the DISK FULL LED echo -n "YYYY" > $DEVICE # Add an EM IP address or if no ethernet, start it up FAIL=1 route -n | grep -q eth0 && FAIL=0 if [ "$FAIL" -eq 0 ]; then FAIL=1 route -n | grep -q 192.168.11.0 && FAIL=0 if [ "$FAIL" -eq 1 ]; then ifconfig eth0:EM 192.168.11.150 netmask 255.255.255.0 up fi else /sbin/ifup --force -a -i /etc/avr-evtd/emergency-eth0 sleep 1 route add -net 192.168.11.0 netmask 255.255.255.255.0 eth0:EM fi if [ -e /sbin/utelnetd ]; then utelnetd -p 1234 -l /bin/bash & if [ -e /etc/init.d/apservd ]; then chmod +x /etc/init.d/apservd /etc/init.d/apservd start fi fi ;; 3) # Flash more lights to indicate we are desperate echo -n "SSSS" > $DEVICE if [ ! -e /etc/passwd.em ]; then cp -f /etc/passwd /etc/passwd.em ; fi if [ ! -e /etc/shadow.em ]; then cp -f /etc/shadow /etc/shadow.em ; fi if [ ! -e /etc/group.em ]; then cp -f /etc/group /etc/group.em ; fi if [ ! -e /etc/gshadow.em ]; then cp -f /etc/gshadow /etc/gshadow.em ; fi if [ ! -e /etc/issue.net.em ]; then cp -f /etc/issue.net /etc/issue.net.em ; fi tar xvf /etc/avr-evtd/recovery.tar ;; *) exit -2 ;; esac ;; 3) echo -n "[avr-evtd]: Power Button Up" ;; 4) echo -n "[avr-evtd]: Power Button Down" ;; 5) echo -n "[avr-evtd]: Reset Button Up" ;; 6) echo -n "[avr-evtd]: Reset Button Down" ;; 1|2|7) echo -n "[avr-evtd]: Shutdown" echo -n "]]]]EEEE" > $DEVICE # Perform shutdown request shutdown -h now ;; 8) echo -n "[avr-evtd]: User demanded reset" echo -n "]]]]CCCC" > $DEVICE # Perform reboot reboot ;; 9) if [ "$3" -eq 0 ]; then echo -n "[avr-evtd]: Disk usage now safe" else echo -n "[avr-evtd]: Disk used $3% > Monitored $DISKCHECK%" fi ;; E) echo -n "[avr-evtd]: EM mode selected" if [ "$EMMODE" = "YES" ]; then # Determine flash block to use, default to 2 if [ -f /proc/mtd ]; then MTD=`cat /proc/mtd | grep mtd_status` BLOCK_ID=${MTD:3:1} if [ -z "$BLOCK_ID" ]; then BLOCK_ID=2 ; fi FLASH=/dev/mtdblock$BLOCK_ID else ls -al /dev/fl3 | grep -q "250,[ ]*3" && FLASH=/dev/fl3 fi # Flash device available? if [ -n "$FLASH" ]; then # Check we are dealing with a buffered device? if [ ! -b $FLASH ]; then echo "$FLASH device does not exist, no EM-Mode available" >&2 else DUMP=`cat $FLASH` STATE=${DUMP:2:4} # Check state is currently NORMAL if [ "$STATE" = "OKOK" ]; then echo -n "NGNGNG" > $FLASH fi echo -n "]]]]CCCC" > $DEVICE /sbin/reboot fi fi fi ;; F) echo -n "[avr-evtd]: Fan failure detected" if [ "$3" -eq 0 ]; then logger -p user.emerg -i 'AVR Detected fan fault' fi if [ "$3" -eq 4 ]; then # Illuminate relevant LED and wait for AVR halt message echo -n "iiii" > $DEVICE fi ;; S) if [ "$3" -gt 100 ]; then MESSAGE="System shutdown in less than 5 minutes" else MESSAGE="Shutdown delayed by $3 minutes" fi # Produce relevant message logger -p user.emerg -i $MESSAGE ;; D) MESSAGE="[$3] Error with configuration file" logger -t $tag -p $facility -i $MESSAGE ;; *) exit 1 ;; esac exit 0 avr-evtd-1.7.7/README.IMPORTANT0000644000175000017500000000130311375374323015103 0ustar rbritorbritoFollowing major changes with the daemon and the support scripts, some of the functions of the reset and power buttons have been changed. These mostly affect the reset button. The reset feature has been removed (as power button can perform this feature) and instead this can be used to selected EM-Mode (HDD diaster recovery feature of the LS/Kuro). If the reset button is held for at least 20 seconds then a message is written to the flash memory and a reboot is issued. At this point, the box is now in EM-Mode as it has booted from ram flash and not HDD image. PLEASE NOTE, THIS IS FOR USE ONLY BY THOSE WHO ARE AWARE OF THE ISSUES OF ENTERING EM-MODE. DO NOT USE OTHERWISE YOUR HDD DATA IS AT RISK. avr-evtd-1.7.7/Makefile0000644000175000017500000000407111375374323014314 0ustar rbritorbrito# # Makefile for the Linkstation AVR Event daemon running under Linux # # Copyright 2008 Bob Perry # Copyright 2008, 2009 Rogério Brito TITLE=Linkstation AVR Event daemon # # User configurable variables # # Add -DUBOOT to the build process if you are using U-Boot as this will # remove the redundant EM-Mode NGNGNG poke into flash # CC = cc CFLAGS = -Wall -Wextra -Os CFLAGS += -DUBOOT ###################################################################### # Almost no user should need to change the contents below ###################################################################### # We have the option to build the daemon for PPC or MIPS ifeq (, $(PREFIX)) PREFIX := usr/local endif MACHINE = $(shell uname -m) ifeq (${MACHINE}, mips) CFLAGS += -DMIPS endif ifneq (, $(shell test -d /etc/melco)) CFLAGS += -DNO_MELCO endif # Main targets all: avr-evtd avr-evtd: avr-evtd.c $(CC) $(CFLAGS) -o avr-evtd avr-evtd.c clean: rm -f avr-evtd rm -f /etc/init.d/avr-evtd rm -f /etc/default/avr-evtd.sample rm -f /etc/avr_evtd/EventScript rm -f /usr/local/sbin/avr-evtd rm -f /usr/local/man/man8/avr-evtd.8 install: avr-evtd # ENSURE DAEMON IS STOPPED if [ -e /etc/init.d/avr-evtd ]; then /etc/init.d/avr-evtd stop ; fi install -D -m 755 Install/avr-evtd.init $(DESTDIR)/etc/init.d/avr-evtd # ENSURE LOCAL DIRECTORY EXISTS AND UPDATE EXECUTABLE install -D -m 755 avr-evtd $(DESTDIR)/$(PREFIX)/sbin/avr-evtd # TRANSFER EVENT SCRIPT install -D -m 755 Install/EventScript $(DESTDIR)/etc/avr-evtd/EventScript install -D Install/emergency-eth0 $(DESTDIR)/etc/avr-evtd/emergency-eth0 install -D -m 644 Install/recovery.tar $(DESTDIR)/etc/avr-evtd/recovery.tar # ENSURE DEFAULT AVAILABLE if [ ! -e /etc/default/avr-evtd.config ]; then \ install -D Install/avr-evtd.config $(DESTDIR)/etc/default/avr-evtd.config ; else \ install -D Install/avr-evtd.config $(DESTDIR)/etc/default/avr-evtd.sample ; fi # ENSURE LOCAL MAN AVAILABLE install -D Install/avr-evtd.8 $(DESTDIR)/$(PREFIX)/share/man/man8/avr-evtd.8 start: /etc/init.d/avr-evtd start avr-evtd-1.7.7/Changelog.old0000644000175000017500000000353411375374323015246 0ustar rbritorbritoV1.7.4 Changes to the building system (fixes the Melco detection etc). Changes to the building system (respects DESTDIR). Changes to the directory layout. Fix the init script so that it works with dependency-based boot systems. Convert occurrences of avr_evtd to avr-evtd. V1.7.3 Changes to configuration filename. 22 Inclusion in the sourceforge repository and small bugfixes. V1.7.2 Script changes. Additions to run script in background and added 5 minute shutdown event and moved other event messages to the system. V1.7.1 Minor fixes to the config parser. Changes to the keep alives to allow user control over DISK FULL LED V1.7 Allow running without fan. A bit more code reduction. Allow the user to specify checked drive partitions so to cater for those with customised drives. V1.6.3 Correct rounding down in disk usage calculations. Also corrected time skew as a result of user/ntp time updates. V1.6.2 Script changes only. V1.6.1 Offical release. Improvements to code size. Additions made to scripts for 'boost' cooling at shutdown/reboot (following issues in hot environments). Fixes to timer calcs. V1.6 Improve available timer resolution. Provided 'paused' shutdown which inhibits timer revalidation as clock is now wrong. Aid CPU loading but also pick up timer demands shortly after init. so long refresh periods are caught. Fixed bug with finding off time as current. Corrected AVR message 0x31 to a halt request. Profiled code. V1.5 Introduced macro'd ON/OFF control. Many changes made to default and melco file detection. User control over button detection times and daemon refresh rates. V1.4 Conditional compilation #def's added for NO_MELCO V1.3 Added fan fault messaging. V1.2 Changes to UART initialisation. Code added to support MIPS range. V1.1 Project renamed. Disk check introduced. V1.0 Release avr-evtd-1.7.7/COPYING0000644000175000017500000004310311375374323013706 0ustar rbritorbrito GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. avr-evtd-1.7.7/README1st.txt0000644000175000017500000001374611375374323015013 0ustar rbritorbritoAVR EVENT DAEMON (PPC-EVTD) Copyright © 2006 Bob Perry Copyright © 2008-2010 Rogério Brito This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -------------------------------------------------------------------------------- 1. USAGE: The avr-evtd daemon is aimed at the Buffalo series of Linkstation and Kurobox. This replaces the existing ppc_uartd daemon. The daemon configures the AVR and provides the necessary 'keep-alives' to the AVR watchdog timer. The daemon also checks that the /mnt and / filesystems are within scope (disk space remaining) and also monitors the power button and the 'red' reset button. These button events are turned into requests into the EventScript. This allows a user to control what occurs (system wise) when an event is received. The same script is also used by the timer shutdown process. 2. SYSTEM REQUIREMENTS: Linkstation or equivalent. Either stock or custom kernel and either standard or Debian distribution. 3.INSTALLATION: If you have the GCC tools installed, rebuild and install the process by typing: make make install Remove the current start and shutdown symbolic links for the ppc_uartd: update-rc.d -f ppc_uartd remove Create the new symbolic links: update-rc.d avr-evtd start 12 2 . stop 95 0 6 . This daemon can use either the existing melco provided files or a custom configuration file. This custom file should exist within the /etc/default directory. Just edit the sample file contained there and move: mv avr-evtd.sample avr-evtd 4. CREDITS: The Linkstation and Kuro communities. 5. REVISION HISTORY: 1.7.2 Script corrections to the ip control and routing check. Other changes to daemon to allow script to run in background to improve performance. New event 'S' added to indicate 5 minute shutdown warning. 1.7.1 Some minor corrections to the parser. Changes to the keep alive mechanism to allow user control over the disk full LED. 1.7 Early additions for ntp time creep. Allow box to run without fan. A bit more code reduction. Allow the user to specify checked drive partitions so to cater for those with customised drives. 1.6.3 Minor code changes to 'round' up disk usage calculations. Changes to configuration file, more readable. Added control over location of debug log files. Changed the 'special event' to flash the DISK FULL LED to provide some form of feedback of selected mode. 1.6.2 Changes to EventScript to correct telnet session launch and to add launching of the apservd firmware updater daemon. 1.6.1 More code reduction. Error reporting changed. Updated man pages to reflect changes. Corrections to EM-Mode for the MIPS. Corrections to scripts for shutdown/reboot. Added fan speedup on shutdown/reboot. 1.6 Changes to many things again. Improved timer sleep resolution. Addition of paused shutdown. Reducing CPU loading. Bug fixes to macro'd timer modes. Corrected AVR message 0x31. Added EM-Mode to the event script and changed mode of the reset button. Changed the fan fault to provide a scripted shutdown path - following reported fan failures on my HG. 1.5 Changes to almost everything. Added macro'd power on/off events to allow multiple on/off events each day. Days can be grouped (if similar times) or removed if the unit is not required to be powered on. More control added to refresh rates and power hold down cycles. Control over disk full event messages added. Minor bugs in shutdown timer corrected to allow shutdown for the following day of power on. Standard SHUTDOWN and POWERON now operate as default times if no macro times are specified. Can be removed if no default is required. Double reset event added to launch telnet daemon. Fan monitoring added. Many more changes made too. 1.4 Changes to the EventScript for the MIPS with debian loads. Changes to the Makefile to add proper install process and creation of an Install directory containing all the other parts of the package. Slight corrections to the daemon and addition of NO_MELCO compilier option to reduce build if melco scripts are not used. 1.3 Modified the start and event scripts to pick up UART device from kernel. Output fan fault messages and attempt slow down after 5 minutes. 1.2 Few more typo's fixed. Added MIPSEL support and changed the makefile to autodetect the device.Changed the operation such that the defered configuration files are the melco ones. If /etc/melco is removed, then the /etc/default/avr_evtd configuration files are used. These are also monitored for timer update. Added configuration for the remaining disk warning and extracted event out to the EventScript. 1.1 Renamed from ppc to avr. Cleaned some typo's from this document. Changes to EventScript to add comments and add three new events (7, 8 and 9). Changes to avr_evtd launch script for comments and try and decode UART required from the machine name. Release (1.0) 6. KNOW ISSUES: None known. Tested now on PPC, MIPS and KURO systems with 2.4 and 2.6 releases of the kernel. Also tested under stock, openlink and freelink versions of the updated firmware. -------------------------------------------------------------------------------- This is Free Software for Linkstation/kuro fans and lovers! Please just mention my name if modified or linked to. Bob Perry (UK) JUNE 2006. Rogério Brito Aug 2009.