#! /bin/sh # This is a shell archive. Type 'sh ' to unpack. echo x - log_full.sh cat >log_full.sh <<'MKSHAR_EOF' #!/usr/bin/ksh ( PROG=`basename $0` USER_LIST=informix # BACKUP_CMD="onbar -l" BACKUP_CMD="ontape -a" EXIT_STATUS=0 EVENT_SEVERITY=$1 EVENT_CLASS=$2 EVENT_MSG="$3" EVENT_ADD_TEXT="$4" EVENT_FILE="$5" case "$EVENT_CLASS" in 23) # onbar assumes no operator is present, # so all messages are written to the activity # log and there shouldn't be any output, but echo $* # send everything to /dev/null just in case c=1 for b in $3; do if [[ $c -eq 3 ]]; then logno=$b; fi c=$(( c + 1 )) done $BACKUP_CMD <&1 >> /dev/null n EOF EXIT_STATUS=$? mv $INFORMIXDIR/archives/logfile $INFORMIXDIR/archives/logfile.$logno touch $INFORMIXDIR/archives/logfile chmod 660 $INFORMIXDIR/archives/logfile compress $INFORMIXDIR/archives/logfile.$logno & ;; # One program is shared by all event alarms. If this ever gets expanded to # handle more than just archive events, uncomment the following: *) # EXIT_STATUS=1 ;; esac ) >>$INFORMIXDIR/archives/log_sh.log 2>&1 exit $EXIT_STATUS MKSHAR_EOF echo x - README.1st cat >README.1st <<'MKSHAR_EOF' Contents of shell archive utils3_ak, submitted by Art S. Kagel: Version dated: July 1, 1998 ---------------------------------------------------------------------------- Utility: log_full.sh Synopsis: Version of Informix log_full.sh sample event script to backup automatically logical logs to disk using ontape -a triggered by the log completed event. Author(s): Informix and Art S. Kagel Revision: 1.0 Features Version: 1.0 Version(s) supported: 7.xx File(s): log_full.sh Comments: Be sure to adjust the directory and file name of the log archive file to match the value of the ONCONFIG parameter LTAPEDEV. If the IDS engine is running you will have to use onmonitor to change LTAPEDEV for the running instance. You will have to bounce the engine to install this script as the event handler (modify the ONCONFIG parameter ALARMPROGRAM). Release Notes: ---------------------------------------------------------------------------- Utility: eventalarm Synopsis: General purpose event alarm handler executable. This currently handles several common events which need service or watching. It will send email to any number of administrators and if your pager company has email support (usually you just have to ask them to enable it) it can even email your text pager. This version added support for event #23 Logical Log Completed. It launches an ontape -a command, assuming the logs will be archive to a disk file, renames the file, and prepares for the next log backup. Using a simple lock file technique it does not attempt to run if it is already running, which can happen during heavy activity, allowing the currently running ontape (or the next log complete event) to back up the newest log. It uses a configuration file to know where to write it's own log file, how frequently to notify of repeated events (like lock table overflow), to whom to email notices and the command to use to compress logfiles after they are backed up. It reads the log archive file location from the ONCONFIG file permitting it to be easily installed on multiple sites without recompiling and permitting the DBA to change the location of the log archive files with onmonitor on the fly. Revision 1.19 added direct support for systems which dump log files to /dev/null. A sample config file is included (eventalarm.cfg). Author(s): Alan Chang and Art S. Kagel Revision: 1.22 Features Version: 3.0 Version(s) supported: 7.xx File(s): eventalarm.c, eventalarm.cfg, readn.c, gservlog.c Comments: Logs all events. The template of the code treats events differently by severity level (1-5). The code layout makes it easy to add support for new events. If the IDS engine is running you will have to use onmonitor to change LTAPEDEV for the running instance. You will have to bounce the engine to install this program as the event handler the first time after modifying the ONCONFIG parameter ALARMPROGRAM. The program looks for its configurations file, eventalarm.cfg, in $INFORMIXDIR. Release Notes: Note that for severities 4 & 5 banners are written to a file named /tmp/echo.fifo. In our environment this is a system FIFO which is constantly being read by a process that echos everything it reads from that FIFO to the operators central monitor. I have left this in as a suggestion of one way to notify operations of a problem as it is occurring. You may want to adjust or remove this mechanism. Eventalarm.cfg is a sample configuration file. Readn.c is a function that reads characters until it timesout or reads a newline or specified string. It is used to parse the dialog with ontape. Gservlog is a function that writes a flushed message, preceded by date and time, to a log file. NB: It is not clear, and has not been fully tested, whether the program will properly handle being reprompted for an additional tape. The basic state machine loop that reads and parses the output from ontape should handle this, but testing was minimal as it is not expected to happen since our log files are 100-500MB, the LTAPESIZE is 2GB, and this program should be executed to archive at most two or three log files. Link with readn.c and gservlog.c and -lgen (or whereever your OS/C compiler puts the basename function): gcc -O3 -o eventalarm eventalarm.c gservlog.c readn.c -lgen ---------------------------------------------------------------------------- Utility: cleanlogs Synopsis: Use along with eventalarm. Script and crontab entry to clean up the LTAPEDEV directory of older logfiles. As configured the crontab entry runs the program daily at 9AM and the script deletes any logfiles older than 7 days. It parses the ONCONFIG file for the location of logfiles so it is immune to configuration changes and can be used on multiple instances on the same system. Author: Art S. Kagel Revision: 1.00 Files: cleanlogs crontab ---------------------------------------------------------------------------- MKSHAR_EOF echo x - eventalarm.c cat >eventalarm.c <<'MKSHAR_EOF' /* eventalarm.c - Alarm event program for Informix 7.13+ systems to report Informix events to operators and Administrators. */ /* RCS Header: ----------- $Header: /home/kagel/utils/RCS/eventalarm.c,v 1.22 1999/05/12 13:45:52 kagel Exp $ RCS Log: -------- $Log: eventalarm.c,v $ * Revision 1.22 1999/05/12 13:45:52 kagel * Fixed bug causing a core dump if no af file is specified on the commandline * in an evergency or fatal event. * * Revision 1.21 1999/02/10 15:44:04 kagel * Changed the execlp() call to launch ontape to use a full path of * $INFORMIXDIR/bin/ontape. This solves some problem with 7.24UC7 that * sometimes caused the execlp to fail with errno 2 (no such file or device). * Since getenv() returns INFORMIXDIR correctly it is unlikely that the PATH * is not properly set. Very odd. Anyway this works now. * * Revision 1.20 1998/12/22 17:25:23 kagel * Adjusted initial timeout to 20 seconds to allow for slow ontape startup and * added code to close the pipes and signal ontape to exit on timeout error * or when backing up to /dev/null. * * Revision 1.19 1998/12/16 16:34:48 kagel * Added an exit to log archiving if LTAPEDEV == '/dev/null. * * Revision 1.18 1998/08/14 14:52:06 kagel * *** empty log message *** * * Revision 1.17 1998/08/13 16:12:37 kagel * Removed dependency on Bloomberg's uid/gid for Informix using getpwnam(). * Updated some comments for IIUG users. * * Revision 1.16 1998/07/21 13:54:18 alanc * adding more information for a gservlog statement. * * Revision 1.15 1998/07/20 16:29:38 kagel * Fixed bug in renaming of a single log archive file. * * Revision 1.14 1998/07/17 17:18:04 kagel * Added configurable compressor and cleaned up configuration defaults. * * Revision 1.13 1998/07/17 16:49:30 kagel * Added support for multiple output archive files for very large logs and * to handle the case when logs have not been backed up for a while. * Removed timeout during actual log file archiving to better support large * log files and slow systems. Event lock file now removed before gzipping * the files so another instance of the program can backup subsequent logs if * the compression takes time. * * Revision 1.12 1998/07/01 19:53:10 kagel * emacs eventalarm.c * Saveing Alan's last changes. * * Revision 1.11 1998/06/30 22:26:08 alanc * fixes something. * * Revision 1.10 1998/06/25 18:56:07 kagel * Last changes. Alan enhanced to handle Logical Log complete by * archiving log files with ontape -a. * * Revision 1.9 1998/06/12 16:25:08 alanc * *** empty log message *** * * Revision 1.8 1997/11/17 15:01:45 kagel * typeo. * * Revision 1.7 1997/11/17 14:57:56 kagel * Fixed temp string size in attention() and fflush() fclose()/pclose() * in all message handler routines. These were called even if the output * file/pipe was not opened successfully. * * Revision 1.6 1997/07/14 16:55:58 kagel * Fixed Class two messages to prevent them from mailing. These are * informational only (though subclass 23 log completed can be trapped to * trigger an manual backup of the log). * Added errno printout if cannot open af (assertion failure) file. * * Revision 1.5 1997/07/11 15:21:57 kagel * Added config file parameters. Fixed core dump problems. Added features. * Cleaned up messages logging. * * Revision 1.4 1996/10/02 16:46:51 kagel * Fixes. * * Revision 1.3 1996/09/24 18:04:55 kagel * Fixed situation where no special message is passed. Also removed extraneous * free()/malloc() pairs for temp which only needs to be allocated once. Also * initialized the argument pointers to NULL. * * Revision 1.2 1996/09/24 17:56:54 kagel * Fixed handling of situation where no af file is passed. * */ static char RCSHeader[] = "$Header: /home/kagel/utils/RCS/eventalarm.c,v 1.22 1999/05/12 13:45:52 kagel Exp $"; static char RCSWhat[] = "$What: <@(#) eventalarm.c,v 1.22> $ $Date: 1999/05/12 13:45:52 $"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include static char *errormsg[] = { "Dummy", "1. Table failure", "2. Index failure", "3. Blob failure", "4. Chunk is off-line, mirror is active", "5. DBSpace is off-line", "6. Internal Subsystem failure", "7. OnLine Initialization failure", "8. Physical Restore failed", "9. Physical Recovery failed", "10. Logical Recovery failed", "11. Cannot open Chunk", "12. Cannot open Dbspace", "13. Performance Improvement possible", "14. Database failure.", "15. Data Replication failure.", "16. Archive completed.", "17. Archive aborted.", "18. Log Backup completed.", "19. Log Backup aborted.", "20. Logical Logs are full - Backup is needed.", "21. OnLine resource overflow", "22. Long Transaction detected", "23. Logical Log Complete", "24. Unable to Allocate Memory" }; char recipients[2049]; void attention(int eveid, int classid, char *msg, char *spemsg); void emergency(int eveid, int classid, char *msg, char *spemsg, char *af); void fatalerror(int eveid, int classid, char *msg, char *spemsg, char *af); int readn( int fd, char buf[1025], int len, int flag ); int set_timeout( int secs, int usecs ); void gservlog(char *fmt, ...); extern FILE *GSERVLOG; extern char *GSPARG; int main (int argc, char *argv[]) { int eveseve, eveclassid, i; char *eveclassmsg = NULL, *evespemsg = NULL, *afname = NULL, *informixdir; FILE *fil, *cfg, *ef, *f23; time_t t, ltime; char config[2049], logfile[2049], tapeprog[1025], tmpstr[2049], tmpstr2[2049], tmpstr3[2049]; int delay = 60, fil2, fds1[2], fds2[2], ret; char *tok, *tok23; static char buff[1025], logfile23[1025], old_logfile[1025]; static char logfiles[100][1025], lognum[30], compressor[1025]; char buff23[1024], prompt[20]; struct stat stbuf; int nr, ld, rfd, wfd, nlfiles = 0; pid_t cpid, cpid2, opid; int oldnum = 0; struct passwd *pwd; sprintf( config, "%s/eventalarm.cfg", getenv( "INFORMIXDIR" ) ); /* Get configuration file. */ cfg = fopen( config, "r" ); /* One day change this from positional to tagged data format. */ if (cfg) { /* Line 1: Read list of mail recipients. */ if (fgets( recipients, 2049, cfg ) != (char *)NULL) recipients[strlen(recipients)-1] = (char)0; else /* Empty file? Default to no email. */ recipients[0] = (char)0; /* Line 2: Read logfile path. This path is for eventalarm to log its activity */ if (fgets( logfile, 2049, cfg ) != (char *)NULL) logfile[strlen(logfile)-1] = (char)0; else /* No second line? Default to current directory. */ logfile[0] = (char)0; /* Line3: Read delay between multiple identical event reports (secs). */ if (fgets( tmpstr, 2049, cfg ) != (char *)NULL) { tmpstr[strlen(tmpstr)-1] = (char)0; delay = atoi( tmpstr ); } else { /* No third line? Default to once a minute. */ delay = 60; } /* Line4: Read compressor program command line. */ if (fgets( compressor, 2049, cfg ) != (char *)NULL) compressor[strlen(compressor)-1] = (char)0; else /* No fourth line? Default to gzip. */ strcpy( compressor, "gzip" ); } else { /* No config file? Set defaults as above. */ recipients[0] = (char)0; logfile[0] = (char)0; delay = 60; strcpy( compressor, "gzip" ); } if (strlen( recipients ) == 0) /* Always send mail to informix. */ strcpy( recipients, "informix" ); if (strlen( logfile ) == 0) /* Default path to IDS startup directory. */ sprintf( logfile, "./%s.log", basename(argv[0]) ); if (logfile[strlen(logfile)-1] == '/') /* Path only. Default name. */ strcat( logfile, basename(argv[0]) ); fil = fopen( logfile, "a" ); GSERVLOG = fil; GSPARG = ""; t = time( NULL ); /* gservlog( "%s", asctime( localtime( &t ) ) ); */ if ( argc >= 6 && *argv[5] ) { eveseve = atoi(argv[1]); eveclassid = atoi(argv[2]); eveclassmsg = (char *) malloc(strlen(argv[3])+1); evespemsg = (char *) malloc(strlen(argv[4])+1); strcpy(eveclassmsg, argv[3]); strcpy(evespemsg, argv[4]); afname = (char *) malloc(strlen(argv[5])+1); strcpy(afname, argv[5]); } else if (argc >= 5) { eveseve = atoi(argv[1]); eveclassid = atoi(argv[2]); eveclassmsg = (char *) malloc(strlen(argv[3])+1); evespemsg = (char *) malloc(strlen(argv[4])+1); strcpy(eveclassmsg, argv[3]); strcpy(evespemsg, argv[4]); } else if (argc >= 4) { eveseve = atoi(argv[1]); eveclassid = atoi(argv[2]); eveclassmsg = (char *) malloc(strlen(argv[3])+1); strcpy(eveclassmsg, argv[3]); } switch(eveseve){ case 1: gservlog( "Not noteworthy event: Severity=%d, Class=%d.\n", eveseve, eveclassid ); break; case 2: gservlog("NonFatal Event: Severity=%d, Class=%d.\n", eveseve, eveclassid ); break; case 3: gservlog("Attention Event: Severity=%d, Class=%d.\n", eveseve, eveclassid ); break; case 4: gservlog("Emergency Event: Severity=%d, Class=%d.\n", eveseve, eveclassid ); system("banner INFORMIX 'MAY BE' DOWN >> /tmp/echo.fifo"); break; case 5: gservlog("Fatal Event: Severity=%d, Class=%d.\n", eveseve, eveclassid ); system("banner INFORMIX IS DOWN >> /tmp/echo.fifo"); system("/usr/bin/echo INFORMIX IS DOWN >> /tmp/echo.fifo"); break; default: gservlog("Unknown Severity ID %d, Class Id %d\n", eveseve, eveclassid); break; } gservlog( "%d args passed\n", argc ); for (i=0;i 4) fatalerror( eveseve, eveclassid, eveclassmsg, evespemsg, afname ); else if (eveseve > 3) emergency( eveseve, eveclassid, eveclassmsg, evespemsg, afname ); else if (eveseve > 2) attention( eveseve, eveclassid, eveclassmsg, evespemsg ); break; case 21: /* Online resource overflow. */ sprintf( tmpstr, "event.S%d.C%d", eveseve, eveclassid ); ef = fopen( tmpstr, "r+" ); if (!ef) { ltime = 0; ef = fopen( tmpstr, "w" ); if (!ef) { gservlog( "Cannot open timer file for this event!\n" ); } } else fread( <ime, sizeof ltime, 1, ef ); if (!ef || (ltime + delay) < t) { /* Only message once for each period. */ if (eveseve > 4) fatalerror(eveseve, eveclassid, eveclassmsg, evespemsg, afname ); else if (eveseve > 3) emergency( eveseve, eveclassid, eveclassmsg, evespemsg, afname ); else if (eveseve > 2) attention( eveseve, eveclassid, eveclassmsg, evespemsg ); fseek( ef, 0, SEEK_SET ); fwrite( &t, sizeof t, 1, ef ); sprintf( tmpstr, "'(onstat -k -g ses; nps -e -o uname,pid,ppid,pgid," "sid,nlwp,cpu,dglstate,stime,time,args)>>onstat.k.ses.%s'", getpid() ); tmpstr[strlen(tmpstr)] = '\0'; system( tmpstr ); /* Let's catch the culprit. */ } fflush( ef ); fclose( ef ); break; case 23: /* Logical Log Completed. */ sprintf( tmpstr2, "event.S%d.C%d", eveseve, eveclassid ); strcpy(tmpstr3, tmpstr2); opid = getpid(); fil2 = open( tmpstr2, O_CREAT|O_EXCL|O_RDWR, 0600); if (fil2 == -1) { /* There may be an old lockfile left around. Cleanup. */ if (errno == EEXIST) { errno = 0; fil2 = open( tmpstr2, O_RDWR, 0600); } if (errno && errno != EPERM) { gservlog( "Removing old lock file.\n" ); unlink( tmpstr2 ); fil2 = open( tmpstr2, O_RDWR|O_CREAT, 0600); if (errno) { gservlog( "Could not recreate lock file. /n " ); return 6; } pwrite(fil2, &opid, 4, 0 ); } else if (errno == EPERM) { gservlog( "No permissions on lockfile: %s.\n", tmpstr2 ); return 7; } else if (pread( fil2, &opid, 4, 0 ) == 0 || (ret = kill(opid,0)) == 0 || /* Is this pid still there? */ (ret == -1 && errno == EPERM)) { gservlog("ontape is already running.\n"); close( fil2 ); break; } } strncpy(buff, eveclassmsg, 1024); buff[1023] = (char)0; tok = strtok(buff, " "); tok = strtok(NULL, " "); tok = strtok(NULL, " "); strcpy( lognum, tok ); /* Open two uni-directional pipes for communication between parent and child. */ if (pipe(fds1) < 0) { fprintf(stderr, "Pipe 1 open failed! Errno=%d.\n", errno ); exit(9); } if (pipe(fds2) < 0) { fprintf(stderr, "Pipe 2 open failed! Errno=%d.\n", errno ); exit(9); } if ((cpid = fork()) == 0) { /* Child code. */ /* Make our two uni-directional pipes into a bi-directional pipe, hook it into stdin/stdout and launch ontape -a */ close(0); /* Close stdin */ dup( fds1[0] ); /* Make pipe file 0 stdin */ close(1); /* Close stdout */ dup( fds2[1] ); /* Make pipe file 1 stdout */ close(2); /* Close stderr */ dup( fds2[1] ); /* Make pipe file 1 stderr also */ /* Exec ontape */ informixdir = getenv( "INFORMIXDIR" ); sprintf( tapeprog, "%s/bin/ontape", informixdir ); execlp( tapeprog, "ontape", "-a", (char *)NULL ); gservlog( "Exec of ontape failed! Errno=%d.\n", errno ); exit(8); } else { /* Parent code. */ opid = getpid(); pwrite( fil2, &opid, 4, 0 ); gservlog( "Ontape -a started as pid: %d\n", cpid ); /* Hook parent into pipe and create a stream from the output fd for ease of use. The parent uses the opposite side of each pipe from that used by the child. */ rfd = fds2[0]; /* File descriptor for reading */ wfd = fds1[1]; /* File descriptor for writing */ f23 = fdopen( wfd, "w" ); /* Stream for writing */ /* Get the Informix uid and gid, in case the engine is running as root. */ pwd = getpwnam( "informix" ); set_timeout( 20, 0 ); strcpy(prompt, " ... "); while (1){ strcpy( buff23, prompt ); nr = readn( rfd, buff23, 1024, 3); if (nr == LONG_MIN) { gservlog("Time out\n"); close( 0 ); close( 1 ); close( 2 ); close( fds1[0] ); close( fds1[1] ); close( fds2[0] ); close( fds2[1] ); kill( cpid, SIGPIPE ); kill( cpid, SIGTERM ); return 5; } else if (nr < 0) { nr = nr * -1; gservlog("Time out after %d read\n", nr); } buff23[nr] = (char)0; gservlog( buff23 ); if (buff23[nr-1] != '\n') { fputs( "\n", GSERVLOG ); fflush( GSERVLOG ); } tok23 = strtok(buff23, " "); if (strcmp(tok23, "Please")==0) { tok23 = strtok(NULL, " "); if (strcmp(tok23, "mount" )==0) { tok23 = strtok(NULL, " " ); tok23 = strtok(NULL, " " ); tok23 = strtok(NULL, " " ); tok23 = strtok(NULL, " " ); strcpy( logfile23, tok23 ); if (strcmp( logfile23, "/dev/null" ) == 0) { gservlog( " Logging being dumped to " "/dev/null. Logfile %d " "discarded.\n", lognum ); close( 0 ); close( 1 ); close( 2 ); close( fds1[0] ); close( fds1[1] ); close( fds2[0] ); close( fds2[1] ); kill( cpid, SIGPIPE ); kill( cpid, SIGTERM ); exit( 0 ); } gservlog( " Archiving logfile %s to: %s\n", lognum, logfile23 ); ld=open(logfile23, O_CREAT); close(ld); if ((stat(logfile23, &stbuf)==0) &&(stbuf.st_size)) { oldnum = oldnum + 1; sprintf( old_logfile, "%s.old%d", logfile23, oldnum); errno = 0; while ((link(logfile23, old_logfile)) == -1 && ( errno == EEXIST )) { oldnum = oldnum + 1; sprintf( old_logfile, "%s.old%d", logfile23, oldnum); errno = 0; } if (errno) { gservlog("file %s can't be renamed" ", errno = %d\n", logfile23, errno); errno = 0; } unlink(logfile23); ld=open(logfile23, O_CREAT); close(ld); } chmod(logfile23, 0660 ); /* chmod 660 */ /* chown/chgrp file to informix in case */ /* engine started as root. */ chown(logfile23,pwd->pw_uid,pwd->pw_gid); fputs( "\n", f23); fflush(f23); strcpy(prompt, "? (y/n) " ); /* Disable timeout until logs are backed up. */ set_timeout( 0, 0 ); } } else if (strcmp(tok23, "Tape" )==0){ /* Archive file is full, rename and create a new one. */ sprintf( logfiles[nlfiles], "%s.%s.%d", logfile23, lognum, nlfiles+1 ); link( logfile23, logfiles[nlfiles] ); unlink( logfile23 ); gservlog( "Renamed %s to %s.\n", logfile23, logfiles[nlfiles] ); close( open( logfile23, O_CREAT ) ); chmod( logfile23, 0660 ); strcpy(prompt, " ... "); nlfiles++; } else if (strcmp(tok23, "Do")==0){ fputs( "n\n", f23); fflush(f23); gservlog("n\n"); strcpy( prompt, "Program over.\n" ); } else if (strcmp( tok23, "Program" )==0) { break; } } /* Rename the last log archive file. */ if (nlfiles) /* If more than one file, give this the next gen # */ sprintf( logfiles[nlfiles], "%s.%s.%d", logfile23, lognum, nlfiles+1 ); else /* Otherwise just append the log number. */ sprintf( logfiles[nlfiles], "%s.%s", logfile23, lognum ); link( logfile23, logfiles[nlfiles] ); unlink( logfile23 ); gservlog( "Renamed %s to %s.\n", logfile23, logfiles[nlfiles] ); /* Set up log archive file for the next run. */ close( open( logfile23, O_CREAT ) ); chmod( logfile23, 0660 ); /* Release the lock file so another log event can startup. */ unlink(tmpstr3); /* Compress all logfiles. */ for (; nlfiles>=0;nlfiles--) { sprintf( tmpstr2, "%s %s &", compressor, logfiles[nlfiles] ); gservlog("%s\n",tmpstr2); system( tmpstr2 ); } } close( fil2 ); break; default: if (eveclassid > 24 && eveseve > 2) attention( eveseve, eveclassid, eveclassmsg, evespemsg ); break; } gservlog( "\n" ); /* Force an empty line to the log. */ errno = 0; if ((cpid2 = waitpid(cpid, NULL, 0)) > 0) gservlog( "Child status! Errno=%d.\n", errno ); fflush( fil ); fclose( fil ); exit(0); } void attention(int eveid, int classid, char *msg, char *spemsg) { FILE *f; int sz, sz1, sz2; static char *temp; sz = 256 + ((sz1 = strlen(msg)) > (sz2 = strlen(spemsg)) ? sz1 : sz2); temp = (char *) malloc(sz); sprintf( temp, "mailx -s \"%s\" %s", msg, recipients ); temp[strlen(temp)] = '\0'; f = popen(temp, "w"); if (f) { sprintf(temp, "severity id = %d, classid = %d, msg = %s\n", eveid, classid, msg); temp[strlen(temp)] = '\0'; fputs(temp, f); if (spemsg) { sprintf(temp, "special msg = %s\n", spemsg); temp[strlen(temp)] = '\0'; fputs(temp, f); } fflush( f ); pclose(f); } free(temp); } void emergency(int eveid, int classid, char *msg, char *spemsg, char* afname) { FILE *f, *ofp; char c; static char temp[1025]; sprintf( temp, "mailx -s \"%s\" %s", msg, recipients ); f = popen(temp, "w"); if (f) { fprintf( f, "severity id = %d\n classid = %d\n", eveid, classid ); if (msg) fprintf( f, "msg = %s\n", msg); if (spemsg) { fprintf( f, "special msg = %s\n", spemsg ); } if (afname) { fprintf( f, "See Also File %s's Contents are:\n", afname ); fprintf( f, "================================\n\n"); if ((ofp = fopen(afname, "r")) == NULL) { gservlog( "See Also File mode error, See Also File name = %s(%d)\n", afname, errno ); fprintf( f, "See Also File mode error, See Also File name = %s(%d)\n", afname, errno ); } else while ((c = getc(ofp)) != EOF) putc(c, f); } else { gservlog( "No See Also File\n" ); fprintf( f, "No See Also File\n" ); } fflush( f ); pclose(f); } } void fatalerror(int eveid, int classid, char *msg, char *spemsg, char* afname) { FILE *f, *ofp; char c; static char temp[1025]; sprintf( temp, "mailx -s \"%s\" %s", msg, recipients ); f = popen(temp, "w"); if (f) { fprintf( f, "severity id = %d\n classid = %d\n", eveid, classid ); if (msg) fprintf( f, "msg = %s\n", msg); if (spemsg) { fprintf( f, "special msg = %s\n", spemsg ); } if (afname) { fprintf( f, "See Also File %s's Contents are:\n", afname ); fprintf( f, "================================\n\n"); if ((ofp = fopen(afname, "r")) == NULL) { gservlog( "See Also File mode error, See Also File name = %s(%d)\n", afname, errno ); fprintf( f, "See Also File mode error, See Also File name = %s(%d)\n", afname, errno ); } else while ((c = getc(ofp)) != EOF) putc(c, f); } else { gservlog( "No See Also File\n" ); fprintf( f, "No See Also File\n" ); } fflush( f ); pclose(f); } } MKSHAR_EOF echo x - eventalarm.cfg cat >eventalarm.cfg <<'MKSHAR_EOF' informix infadminstrator@workstation 123456@skypage.com /tmp/eventalarm.echo 1800 gzip -1 MKSHAR_EOF echo x - gservlog.c cat >gservlog.c <<'MKSHAR_EOF' #include #include #include #include #include FILE *GSERVLOG = stderr; char *GSPARG = "Unknown"; void gservlog(char *fmt, ...) { va_list args; static char *mon[] = {"Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"}; long x = time(NULL); struct tm *tml; tml = localtime(&x); lockf(fileno(GSERVLOG),F_LOCK,0); fprintf(GSERVLOG,"%s %.2d %.2d:%.2d:%.2d %s:",mon[tml->tm_mon], tml->tm_mday,tml->tm_hour,tml->tm_min,tml->tm_sec,GSPARG); va_start(args,fmt); vfprintf(GSERVLOG,fmt,args); va_end(args); rewind(GSERVLOG); lockf(fileno(GSERVLOG),F_ULOCK,0); } MKSHAR_EOF echo x - readn.c cat >readn.c <<'MKSHAR_EOF' /* readn.c - Non-blocking read function. Options, depending on the value of * flag to behave like fgets, similarly with an arbritrary EOR string, or after * a fixed length. Timeouts are supported. */ /* RCS Header: ----------- $Header: /bb/source/db/mstrserv/RCS/readn.c,v 1.1 1998/07/17 14:55:10 kagel Exp $ RCS Log: -------- $Log: readn.c,v $ * Revision 1.1 1998/07/17 14:55:10 kagel * Initial revision * */ static char RCSHeader[] = "$Header: /bb/source/db/mstrserv/RCS/readn.c,v 1.1 1998/07/17 14:55:10 kagel Exp $"; static char RCSWhat[] = "$What: <@(#) readn.c,v 1.1> $ $Date: 1998/07/17 14:55:10 $"; static char RCSCompile[] = "$cc: " __FILE__ " " __DATE__ " " __TIME__ " $"; #include #include #include #include #include #include #include #include #include #define FEXPNL 1 #define FEXPST 2 #define FREQRD 4 extern int errno; int readn_errno = 0; static int timeout_secs = 10; static int timeout_usec = 0; void set_timeout( int secs, int usec ) { timeout_secs = secs >= 0 ? secs : timeout_secs; timeout_usec = usec >= 0 ? usec : timeout_usec; if (timeout_usec > 1000000) { timeout_secs += (timeout_usec / 1000000); timeout_usec %= 1000000; } } int readn( int fd, char *buf, int len, int flag ) { char *ptr = buf, EndOfRec[1024]; long nread = 0, nready=0, nleft = len, tread = 0, nl=0, str=0, reqd=0, adj; fd_set readfds; long maxfd = fd + 1; struct timeval starttime, currtime, maxtime; readn_errno = 0; if (flag & FEXPNL) { nl=1; } if (flag & FEXPST) { str=1; strcpy( EndOfRec, buf ); adj = strlen( EndOfRec ); } if (flag & FREQRD) reqd=1; errno = 0; signal( SIGPIPE, SIG_IGN ); FD_ZERO( &readfds ); FD_SET( fd, &readfds ); if (timeout_secs || timeout_usec) { maxtime.tv_sec = timeout_secs; maxtime.tv_usec = timeout_usec; gettimeofday( &starttime, NULL ); currtime.tv_sec = starttime.tv_sec; currtime.tv_usec = starttime.tv_usec; } while (1) { if (nready && FD_ISSET( fd, &readfds )) { nread = read(fd, ptr, 1); if ((ssize_t)nread < 0 && (errno != EAGAIN && errno != EWOULDBLOCK)) { return (ssize_t)LONG_MIN; /* error, return HUGE negative */ } else if ((ssize_t)nread < 0) nread = 0; nleft -= nread; tread += nread; ptr += nread; *ptr = (char)0; if (nleft == 0) break; if (nl && *(ptr-nread) == '\n') break; if (str && strncmp( EndOfRec, (ptr-adj), adj ) == 0) break; } if (timeout_secs || timeout_usec) { maxtime.tv_sec -= (currtime.tv_sec - starttime.tv_sec); maxtime.tv_usec -= (currtime.tv_usec - starttime.tv_usec); if (maxtime.tv_usec < 0) { maxtime.tv_sec--; maxtime.tv_usec += 1000000; } if (maxtime.tv_sec < 0 || (maxtime.tv_sec == 0 && maxtime.tv_usec <= 0)) { readn_errno = -6; if (tread) { return (-1 * (ssize_t)tread); } else return LONG_MIN; } starttime.tv_sec = currtime.tv_sec; starttime.tv_usec = currtime.tv_usec; } FD_ZERO( &readfds ); FD_SET( fd, &readfds ); nready = select( fd + 1, &readfds, NULL, NULL, &maxtime ); if (timeout_secs || timeout_usec) gettimeofday( &currtime, NULL ); } return tread; } MKSHAR_EOF echo x - crontab cat >crontab <<'MKSHAR_EOF' ######################################### # Clean up old logfile archive files # ######################################### # 0 9 * * * /bb/bin/informix/bin/cleanlogs MKSHAR_EOF echo x - cleanlogs cat >cleanlogs <<'MKSHAR_EOF' #! /usr/bin/ksh . /usr/bin/informix.7.0 # Script to set up Informix environment. # Really just need INFORMIXDIR and ONCONFIG here. cd `awk '/LTAPEDEV/{nf=split($2,a,"/");for (i=1;i