/* * :set tabstop=4 * vme_acfail.c * spd@daphne.cps.unizar.es * Mon Apr 28 12:48:47 MET DST 1997 * Solaris 2.5 sparc; FORCE VME * */ #include #include #include #include #include #include #include #include #include #include #include /*#include */ /*#include */ /* * gcc 2.7.2.1 doesn't likes * typedef unsigned long long vmeaddr_t * in vme_types.h */ int vui_acfail_wait(int dev); int vui_acfail_signal( int dev, int signal ); #define PATH_SEP '/' static char __ident[] = "@(#)SPDsoft, Mon Apr 28, 1997"; #define VERS_STR ((char*)&__ident[4]) char *app; void (*sigint)(int); int vmedev; int daemon=0; void usage(void); int main (int argc, char **argv); void die(int s); void merror(char *msg); int set_acfail(void); int launch( char *cmd[], int *status ); void usage(void) { fprintf(stderr,"Use: %s [-hd]\n-d:\tdaemon mode\n", app); exit(0); } void merror(char *msg) { int error; if ( daemon ) { error=errno; openlog( app, LOG_PID | LOG_NDELAY | LOG_NOWAIT , LOG_USER); syslog( LOG_ERR, "%s (%s)", msg, strerror(error) ); closelog(); } else { perror(msg); } return; } void die(int s) { char *cmd[] = { /* "/bin/sleep","30",*/ /* NULL*/ "/usr/sbin/shutdown","-y","-g300","-i5", "Power fail", NULL }; int status; int error; sigignore(SIGINT); openlog( app, LOG_PID | LOG_NDELAY | LOG_NOWAIT , LOG_USER); syslog( LOG_EMERG, "Power Fail, I'm going down" ); closelog(); if(0==(error=launch( cmd, &status))) { if ( status == 0 ) exit(0); } else { openlog( app, LOG_PID | LOG_NDELAY | LOG_NOWAIT , LOG_USER); syslog( LOG_ERR, "execvp failed (%s)", strerror(errno) ); closelog(); } return; } int main (int argc, char **argv) { extern char *optarg; extern int optind,opterr; int opt; int st=0; if ((app = strrchr(argv[0], PATH_SEP)) != NULL) app = app+1; else app = argv[0]; while ( (opt=getopt(argc,argv,"hdV")) != EOF ) { switch(opt) { case 'd': daemon=1; break; case 'V': fprintf(stdout,"%s\n", VERS_STR); exit(0); break; case 'h': default: usage(); break; } } if ((vmedev = open ("/dev/vmectl", O_RDWR)) == -1) { perror ("open /dev/vmectl"); st = -1; } else { if (!daemon) { char name[32]; short id; if ( 0 == vui_board( vmedev, name, &id )) fprintf(stderr, "%s: Board: %s (%d)\n", app, name, id); if ( 0 == vui_interface( vmedev, name, &id )) fprintf(stderr, "%s: Interface: %s (%d)\n", app, name, id); } else { freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); if (fork()) exit (0); } close (vmedev); while ((st == 0) && ( 0 == (st = set_acfail()))) { if ( SIG_ERR == (sigint=sigset(SIGINT, die))) { merror("sigset"); st=-1; } else { sigpause(SIGINT); } } } exit(st); } /*************************************************************************/ int launch( char *cmd[], int *status ) { int res=0; int st; int pid; char s[256]; switch ( pid = fork() ) { case -1: /* error */ merror ( "fork" ); res = -1; break; case 0: sigset(SIGINT, sigint); execvp ( cmd[0], &cmd[0] ); merror("execvp"); exit(-2); break; default: *status = 0; while ( pid != wait ( &st )) { if (( st == -1 ) && ( errno != EINTR )) merror("wait"); } if (WIFSTOPPED(st)) { sprintf(s,"%s: %s stoped %d\n", app, cmd[0], WSTOPSIG(st)); merror(s); res = -6; } else if(WIFEXITED(st)) { *status = WEXITSTATUS(st); } else if(WIFSIGNALED(st)) { sprintf(s,"%s: %s signaled %d\n", app, cmd[0],WTERMSIG(st)); merror(s); res = -6; } if(st&0200) { sprintf(s,"%s: %s core dumped\n", app, cmd[0]); res=-7; } break; } return res; } int set_acfail(void) { int st=0; if ((vmedev = open ("/dev/vmectl", O_RDWR)) == -1) { merror ("open /dev/vmectl"); st = -1; } else { if ( 0 != vui_acfail_signal(vmedev, SIGINT)) { merror("acfail_signal"); st=-1; } close (vmedev); } return(st); }