Subject: parsing oncheck output From: johnl@informix.com (Jonathan Leffler) Date: Tue, 17 Jun 1997 11:26:30 -0700 >I've written a short script to run all of the consistency checks >recommended in chapter 31 of the Administrator's Guide: > >[...script deleted...] (I'd say in the interests of brevity if it weren't for the volume of this message:-) >What I'd like to do is run it from crontab and have it mail its output >to a few people. But, oncheck is really verbose! I'd like it to send >mail only if there's an actual problem that someone needs to worry >about. It would be trivial for me to change those backtick calls into >opens of pipes, and have perl parse the output to figure out if it's >worth mailing out. Unfortunately, I have no clue what to look for. >There doesn't seem to be any regular format for what oncheck spews >out, nor is the format of its messages and error indications >documented anywhere that I can find. > >One possible rule might be: > Look for the word "error". Starting with the line that has the word >"error", continue until you reach a blank line. That block of text is >the entire error message for an actual problem. > >If that were true, I could write my script accordingly. It seems like >a plausible rule to me, based on what I've seen of oncheck output so >far, but without documentation I just don't *know*. I don't want to >make a guess that will end up suppressing actual error messages that >we need to see, leading to a false sense of confidence. But I also >don't want to mail out the entire output every day, because people >will stop reading it. > >Can anyone help? Well, I've not tested this code on databases later than about 5.01, but this is an Informix Administration package I put together a few years ago. Don't let the recent dates on the changes fool you; it is rather long-toothed code. It includes ixcheck (a shell script to run oncheck, pretty much as you asked), with a set of sed filters ixcheck-cX where the X is one of the oncheck options. You will probably need to adjust the filters -- let me know about the changes. It is designed to be run by cron; there is an outgoing mail filter which only send non-empty emails. There are also the startup scripts which I use to run ODS and IUS on my machine at boot time, and which take ODS and IUS down when the machine is shutdown gracefully (as opposed to disgracefully just switching it off:-) And there are the current versions of the scripts I use to copy parts of Informix installations around. Yours, Jonathan Leffler (johnl@informix.com) #include : "@(#): shar.sh,v 1.10 1997/06/02 21:45:00 johnl Exp $" #! /bin/sh # # This is a shell archive. # Remove everything above this line and run sh on the resulting file. # If this archive is complete, you will see this message at the end: # "All files extracted" # # Created: Tue Jun 17 11:18:44 PDT 1997 by johnl at Informix Software Ltd. # Files archived in this archive: # Install.mk # Makefile # basename.c # clnpath.c # clnpath.h # cpinfxdir.1 # cpinfxdir.sh # crontab # dirname.c # fl.c # getopt.h # getpwd.c # informix.1 # instfile.sh # ius.rc # ixadm.bod # ixadm.ins # ixadm.lst # ixcheck-cD # ixcheck-cI # ixcheck-cc # ixcheck-ce # ixcheck-cr # ixcheck.sh # ixchkperm.sh # ixclean.sh # ixcomp.sh # ixconfig.sh # ixcreate.1 # ixcreate.sh # ixcrontab.sh # ixdaily.sh # ixhourly.sh # ixmail.sh # ixmsgpath.sh # ixremove.1 # ixremove.sh # ixrestart.sh # ixrstmsg.sh # ixsetperm.sh # ixstats.sh # ixwarn.sh # ixweekly.sh # ixzero.sh # jlss.h # jlss.sh # mkbod.sh # mkinfxdir.1 # mkinfxdir.sh # mkixcpio.1 # mkixcpio.sh # mkpath.sh # ods.rc # stderr.c # stderr.h # tokenise.c # unixwarn.sh # vstrcpy.c # #-------------------- if [ -f Install.mk -a "$1" != "-c" ] then echo shar: Install.mk already exists else echo 'x - Install.mk (829 characters)' sed -e 's/^X//' >Install.mk <<'SHAR-EOF' X# @(#)$Id: Install.mk,v 1.2 1997/05/12 09:46:35 johnl Exp $ X# X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# X####################### X# Distribution System # X####################### X XBASENAME = ixadm X XFILES.nmd = \ X ${BASENAME}.nmd \ X mknmd \ X mkpath \ X mkversion X XFILES.bod = \ X ${BASENAME}.bod \ X ${BASENAME}.ins \ X ${BASENAME}.lst \ X instfile \ X jlss \ X mkbod \ X mkpath X XNMD: ${FILES.nmd} .FORCE X mknmd . $@ ${BASENAME}.nmd X XBOD: ${FILES.bod} .FORCE X mkbod . $@ ${BASENAME}.bod X X###################################### X# Non-preferred distribution targets # X###################################### X#nmd: ${FILES.nmd} .FORCE X# mknmd . . ${BASENAME}.nmd X# X#bod: ${FILES.bod} .FORCE X# mkbod . . ${BASENAME}.bod X###################################### X Xmkversion: mkversion.sh X rm -f $@ X sh $? $? >$@ X chmod 555 $@ SHAR-EOF chmod 444 Install.mk if [ `wc -c Makefile <<'SHAR-EOF' X# @(#)$Id: Makefile,v 1.9 1997/05/12 09:57:06 johnl Exp $ X# X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# X# Makefile for JLSS Informix Adminstration Tools X XCFLAGS = -O -DUSG_DIRENT X XSCRIPTS = \ X cpinfxdir \ X fl \ X ixcheck \ X ixchkperm \ X ixclean \ X ixcomp \ X ixconfig \ X ixcreate \ X ixcrontab \ X ixdaily \ X ixhourly \ X ixmail \ X ixmsgpath \ X ixremove \ X ixrestart \ X ixrstmsg \ X ixsetperm \ X ixstats \ X ixwarn \ X ixweekly \ X ixzero \ X mkinfxdir \ X mkixcpio \ X unixwarn X XDATAFILES = \ X crontab \ X ixcheck-cD \ X ixcheck-cI \ X ixcheck-cc \ X ixcheck-ce \ X ixcheck-cr X XDOCFILES = \ X cpinfxdir.1 \ X informix.1 \ X ixcreate.1 \ X ixremove.1 \ X mkinfxdir.1 X XFILES.o = \ X fl.o \ X basename.o \ X clnpath.o \ X dirname.o \ X getpwd.o \ X stderr.o \ X tokenise.o \ X vstrcpy.o X Xall: ${SCRIPTS} ${DATAFILES} ${DOCFILES} X Xfl: ${FILES.o} X ${CC} -o $@ ${FILES.o} X Xinclude Install.mk SHAR-EOF chmod 444 Makefile if [ `wc -c basename.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: basename.c,v $ X@(#)Version: $Revision: 1.3 $ X@(#)Last changed: $Date: 1997/04/17 12:14:04 $ X@(#)Purpose: Return basename of filename X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1989,1991,1997 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X#include X X#define NIL(x) ((x)0) X X#ifndef lint Xstatic const char sccs[] = "$Id: basename.c,v 1.3 1997/04/17 12:14:04 johnl Exp $"; X#endif X Xconst char *basename(const char *s) X{ X const char *cp; X X /* Strip trailing slashes, worrying about "/" */ X if ((cp = strrchr(s, '/')) != NIL(char *) && cp > s && cp[1] == '\0') X { X /* Skip backwards over trailing slashes */ X while (cp > s && *cp == '/') X cp--; X /* Skip backwards over non-slashes */ X while (cp > s && *cp != '/') X cp--; X } X X return((cp == NIL(char *) || (cp == s && cp[1] == '\0')) ? s : cp + 1); X} X X#ifdef TEST X#include X Xstatic char *list[] = X{ X "/usr/fred/bloggs", X "/usr/fred/bloggs/", X "/usr/fred/bloggs////", X "bloggs", X "/.", X ".", X "/", X "//", X "///", X "////", X "", X NIL(char *) X}; X Xint main(void) X{ X char **name; X X for (name = list; *name != NIL(char *); name++) X { X printf("%-20s ->", *name); X printf(" '%s'\n", basename(*name)); X } X return(0); X} X#endif /* TEST */ SHAR-EOF chmod 444 basename.c if [ `wc -c clnpath.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: clnpath.c,v $ X@(#)Version: $Revision: 2.4 $ X@(#)Last changed: $Date: 1995/04/05 09:34:18 $ X@(#)Purpose: Clean up pathname (lexical analysis only) X@(#)Author: J Leffler X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X#include X#include "clnpath.h" X X#define MAX_PATH_ELEMENTS 64 /* Number of levels of directory */ X#define strequal(a,b) (strcmp((a),(b)) == 0) X#define DIM(x) (sizeof(x)/sizeof(*(x))) X X#ifdef NO_PROTOTYPES Xextern int tokenise(); X#else Xextern int tokenise(char *, char *, char **, int, int); X#endif /* NO_PROTOTYPES */ X X#ifndef lint Xstatic char sccs[] = "$Id: clnpath.c,v 2.4 1995/04/05 09:34:18 johnl Exp $"; X#endif X X#ifdef NO_PROTOTYPES Xvoid clnpath(path) Xchar *path; /* InOut: Pathname to be cleaned up */ X#else Xvoid clnpath(char *path) X#endif /* NO_PROTOTYPES */ X{ X char *src; X char *dst; X char c; X int slash = 0; X X /* Convert multiple adjacent slashes to single slash */ X src = dst = path; X while (c = *dst++ = *src++) X { X if (c == '/') X { X slash = 1; X while (*src == '/') X src++; X } X } X X if (slash == 0) X return; X X /* Remove "./" from "./xxx" but leave "./" alone. */ X /* Remove "/." from "xxx/." but reduce "/." to "/". */ X /* Reduce "xxx/./yyy" to "xxx/yyy" */ X src = dst = (*path == '/') ? path + 1 : path; X while (src[0] == '.' && src[1] == '/' && src[2] != '\0') X src += 2; X while ((c = *dst++ = *src++) != '\0') X { X if (c == '/' && src[0] == '.' && (src[1] == '\0' || src[1] == '/')) X { X src++; X dst--; X } X } X if (path[0] == '/' && path[1] == '.' && X (path[2] == '\0' || (path[2] == '/' && path[3] == '\0'))) X path[1] = '\0'; X X /* Remove trailing slash, if any. There is at most one! */ X /* dst is pointing one beyond terminating null */ X if ((dst -= 2) > path && *dst == '/') X *dst++ = '\0'; X} X X X/* X** clnpath2() is not part of the basic clnpath() function because it can X** change the meaning of a path name if there are symbolic links on the X** system. For example, suppose /usr/tmp is a symbolic link to /var/tmp. X** If the user supplies /usr/tmp/../abcdef as the directory name, clnpath X** would transform that to /usr/abcdef, not to /var/abcdef which is what X** the kernel would interpret it as. X** One of these days. it should be revised to use strtok(). X*/ X X#ifdef __STDC__ Xvoid clnpath2(char *path) X#else Xvoid clnpath2(path) Xchar *path; X#endif /* __STDC__ */ X{ X char *src; X char *dst; X char *token[MAX_PATH_ELEMENTS]; X int i; X int ntok; X X /* Reduce "/.." to "/" */ X if ((ntok = tokenise(path, "/", token, DIM(token), 0)) > 1) X { X for (i = 0; i < ntok - 1; i++) X { X if (!strequal(token[i], "..") && strequal(token[i + 1], "..")) X { X if (*token[i] == '\0') X continue; X while (i < ntok - 1) X { X token[i] = token[i + 2]; X i++; X } X ntok -= 2; X i = -1; /* Restart enclosing for loop */ X } X } X } X /* Reassemble string */ X dst = path; X for (i = 0; i < ntok; i++) X { X src = token[i]; X while (*dst++ = *src++) X ; X *(dst - 1) = '/'; X } X *(dst - 1) = '\0'; X} X X#ifdef TEST X X/* X** "Certificate of test coverage from LPROF(1)" X** X** Coverage Data Source: clnpath.cnt X** Date of Coverage Data Source: Mon Jul 5 08:16:20 1993 X** Object: ./clnpath X** X** percent lines total function X** covered covered lines name X** X** 100.0 19 19 clnpath X** 100.0 8 8 main X** X** 100.0 27 27 TOTAL X*/ X X#ifndef DIM X#define DIM(x) (sizeof(x)/sizeof(*(x))) X#endif X X#include X X/* This lot stress tests the cleaning, concentrating on the boundaries. */ Xstatic char *grubby[] = X{ X "/", X "//", X "///", X "/.", X "/./", X "/./.", X "/././.profile", X "./", X "./.", X "././", X "./././.profile", X "abc/.", X "abc/./def", X "./abc", X "//abcd///./abcd////", X "//abcd///././../defg///ddd//.", X "/abcd/./../././defg/./././ddd", X "//abcd//././../defg///ddd//.///", X "/usr/tmp/clnpath.c", X "/usr/tmp/", X "sub/directory", X "sub/directory/file" X}; X Xint main() X{ X char buffer[256]; X char **namep; X X for (namep = grubby; namep < grubby + DIM(grubby); namep++) X { X strcpy(buffer, *namep); X clnpath(buffer); X printf("Before: %-32s After: %s\n", *namep, buffer); X } X X#if 0 X /* Interactive testing */ X printf("Enter pathname: "); X while (fgets(buffer, sizeof(buffer), stdin) != NULL) X { X buffer[strlen(buffer) - 1] = '\0'; /* Zap newline */ X printf("Unclean: <<%s>>\n", buffer); X clnpath(buffer); X printf("Clean : <<%s>>\n", buffer); X printf("Enter pathname: "); X } X putchar('\n'); X#endif /* 0 */ X X return(0); X} X X#endif /* TEST */ SHAR-EOF chmod 444 clnpath.c if [ `wc -c clnpath.h <<'SHAR-EOF' X/* X@(#)File: $RCSfile: clnpath.h,v $ X@(#)Version: $Revision: 1.2 $ X@(#)Last changed: $Date: 1997/02/04 14:51:05 $ X@(#)Purpose: Prototypes for path cleaning routines X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1995,1997 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X X#ifndef CLNPATH_H X#define CLNPATH_H X X#ifdef MAIN_PROGRAM X#ifndef lint Xstatic const char clnpath_h[] = "$Id: clnpath.h,v 1.2 1997/02/04 14:51:05 johnl Exp $"; X#endif /* lint */ X#endif /* MAIN_PROGRAM */ X Xextern void clnpath(char *path); Xextern void clnpath2(char *path); X X#endif /* CLNPATH_H */ SHAR-EOF chmod 444 clnpath.h if [ `wc -c cpinfxdir.1 <<'SHAR-EOF' X.\" @(#)$Id: cpinfxdir.1,v 1.1 1997/02/10 14:36:55 johnl Exp $ X.\" @(#)Manual page: Informix Install Utilities X.ds fC "Version: $Revision: 1.1 $ ($Date: 1997/02/10 14:36:55 $) X.TH PROG 1S "JLSS Informix Tools" X.SH NAME Xcpinfxdir \(em create an Informix directory using minimal disk space X.SH SYNOPSIS X\fBc[infxdir\fP [-fv] [-L local] [-R remote] [directory ...] X.SH DESCRIPTION XThe directory specified by the \-L option (defaulting to X${LOCAL:-$INFORMIXDIR}) is populated with the named directories X(defaulting to etc and msg/en_us/0333), and then symbolic links are Xcreated to the INFORMIXDIR specified by the \-R option (defaulting to X${REMOTE:-$ESQLCDIR}) so that the resulting local directory is Xcomplete. XThis allows you to create, for example, a directory where you can have Xlocal OnLine configuration files in the new Informix directory, but Xstill refer to the remote directory (which might typically be XNFS-mounted and readonly) for everything else. X.P XThe \-v option is verbose and cpinfxdir tells you what it is doing as Xit does it. X.P XThe \-f option is forceful and removes everything in the local Xdirectory before doing the copy. X.SH FILES X.SH "SEE ALSO" X.SH DIAGNOSTICS X.SH BUGS XThe third-level fallbacks for $LOCAL and $REMOTE (absolute path names) Xare obscure to the point of uselessness. X.SH AUTHOR XJonathan Leffler X.br XJLSS X.br X10th February 1997 SHAR-EOF chmod 444 cpinfxdir.1 if [ `wc -c cpinfxdir.sh <<'SHAR-EOF' X: "@(#)$Id: cpinfxdir.sh,v 1.3 1997/05/12 08:45:35 johnl Exp $" X# X# Create Copy of Informix Directory X X# Purpose: X# Create a copy of some pre-existing Informix directory by creating X# as few symlinks as possible, subject to the constraint that the X# directories listed in the argument list are actually created as X# local directories, and not as symlinks. This allows, for example, X# the msg/en_us/0333 or etc directories to be created as local X# directories (which can, therefore, be modified), whereas the other X# directories (eg bin or release) are created as symlinks which will X# not, in general, be modifiable. X# X# For use in projects like NewEra. X# X# Usage: X# X# cpinfxdir [-vf] [-L local] [-R remote] [directory ...] X# X# -L specifies the (local) Informix directory to be created X# -R specifies the (remote) Informix directory to be copied X# -f specifies that the existing local directory should be removed X# -v specifies verbose output of what is happening X# X# All directory names specified are relative to $INFORMIXDIR, and X# the default list is "msg/en_us/0333 etc". For many users, a more X# appropriate default would be just etc. The primary default for X# the local directory is $INFORMIXDIR, and the primary default for X# the remote directory is $ESQLCDIR. The secondary defaults are X# weird (because they are specific to NewEra and Anubis) and their X# use is discouraged. X X: ${LOCAL:=${INFORMIXDIR:-${MAKITA:-/vobs/makita}/esqlc}} X: ${REMOTE:=${ESQLCDIR:-/anubis1/informix/7.21.UC1}} X: ${MKPATH:="mkdir -p"} X Xarg0=`basename $0 .sh` Xerror(){ X echo "$arg0: $*" 1>&2 X exit 1 X} X Xverbose=no Xforce=no Xset -- `getopt fvL:R: ${@:+"$@"}` X Xwhile [ $# -gt 0 ] Xdo X case "$1" in X --) shift; break;; X -f) force=yes;; X -v) verbose=yes;; X -L) LOCAL=$2; shift;; X -R) REMOTE=$2; shift;; X *) usage;; X esac X shift Xdone X X# Validate $REMOTE and $LOCAL Xcase "$REMOTE" in X/*) : OK;; X*) error "$REMOTE is not an absolute pathname!";; Xesac Xif [ ! -d $REMOTE ] Xthen error "$REMOTE is not a directory" Xelif [ -f $LOCAL ] Xthen error "$LOCAL is a file!" Xfi X X# Verify required directories under $REMOTE Xdirlist="${*:-msg/en_us/0333 etc}" Xfor dir in $dirlist Xdo X if [ ! -d $REMOTE/$dir ] X then error "$dir does not exist under $REMOTE" X fi X case "$dir" in X /*) error "$dir is not a relative pathname";; X esac Xdone X X# Remove (and recreate) the existing $LOCAL Xif [ $force = yes ] && [ -d ${LOCAL} ] Xthen X [ $verbose = yes ] && echo Remove $LOCAL X rm -fr ${LOCAL} X ${MKPATH} ${LOCAL} Xelif [ ! -d ${LOCAL} ] && [ -h ${LOCAL} ] Xthen X [ $verbose = yes ] && echo "Remove $LOCAL (unattached symlink)" X rm -fr ${LOCAL} X ${MKPATH} ${LOCAL} Xfi X X# Create required directories under $LOCAL Xpathlist="" Xfor dir in $dirlist Xdo X [ $verbose = yes ] && echo Mkdir $LOCAL/$dir X ${MKPATH} ${LOCAL}/$dir X pathlist="$pathlist $dir" X x=`dirname $dir` X while [ "$x" != "." ] X do pathlist="$pathlist $x" X x=`dirname $x` X done Xdone X X# Link all files and directories not already under $LOCAL to $REMOTE Xcd ${LOCAL} Xdirlist=`echo "."; find . -type d -print | sed 's%^\./%%' | sort -u` Xfor dir in $dirlist Xdo X ( X cd $dir X if [ $dir = "." ] X then x=$REMOTE X else x=$REMOTE/$dir X fi X for file in `ls $x` X do X if [ -d $file ] X then : OK X elif [ -f $file ] X then : OK X else X if [ -h $file ] X then X echo "Remove $dir/$file (unattached symlink)" X rm -f $file X fi X [ $verbose = yes ] && echo SymLink $dir/$file X ln -s $x/$file $file X fi X done X ) Xdone SHAR-EOF chmod 444 cpinfxdir.sh if [ `wc -c crontab <<'SHAR-EOF' X# @(#)$Id: crontab,v 1.1 1991/08/20 12:06:23 johnl Exp $ X# CRONTAB for Informix X################################################################### X# Restart system, saving logs (Sundays, 12:03) X3 12 * * 0 /usr/informix/bin/ixweekly X# Compress TBSTAT statistics for yesterday (Daily, 00:37) X37 0 * * * /usr/informix/bin/ixdaily X# Record TBSTAT statistics (Weekdays, hourly; Weekends, 6-hourly) X1 * * * 1-5 /usr/informix/bin/ixhourly X1 0,6,12,18 * * 0,6 /usr/informix/bin/ixhourly SHAR-EOF chmod 444 crontab if [ `wc -c dirname.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: dirname.c,v $ X@(#)Version: $Revision: 1.6 $ X@(#)Last changed: $Date: 1997/04/17 12:14:05 $ X@(#)Purpose: Return directory name for filename X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1989,1991-93,1997 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X#include X#include X#include "stderr.h" X X#define NIL(x) ((x)0) X Xstatic char s_buf[64]; Xstatic size_t s_len = sizeof(s_buf); Xstatic char *s_str = s_buf; X X#ifndef lint Xstatic const char sccs[] = "$Id: dirname.c,v 1.6 1997/04/17 12:14:05 johnl Exp $"; X#endif X Xconst char *dirname(const char *s) X{ X const char *cp; X int c_len; X X /* Strip trailing slashes, worrying about "/" */ X if ((cp = strrchr(s, '/')) != NIL(char *) && cp > s && cp[1] == '\0') X { X /* Skip backwards over trailing slashes */ X while (cp > s && *cp == '/') X cp--; X /* Skip backwards over non-slashes */ X while (cp > s && *cp != '/') X cp--; X } X X if (cp == NIL(char *)) X (void)strcpy(s_str, "."); X else if (cp == s) X (void)strcpy(s_str, "/"); X else X { X c_len = cp - s; X if (c_len > s_len) X { X if (s_str != s_buf) X free(s_str); X s_len = cp - s + 1; X s_str = (char *)malloc(s_len); X if (s_str == NIL(char *)) X error("out of memory"); X } X (void)strncpy(s_str, s, c_len); X s_str[c_len] = '\0'; X } X return(s_str); X} X X#ifdef TEST X#include X X#define DIM(x) (sizeof(x)/sizeof(*(x))) X Xstatic const char *files[] = X{ X "/usr/lib", X "/usr/", X "usr", X "/", X ".", X "..", X"/the/lion/is/the/king/of/the/jungle/and/this/is/more/than/64/chars/long", X"/the/lion/is/the/king/of/the/jungle/and/this/is/much/longer/than/the/other/is", X}; Xstatic const char *dirs[] = X{ X "/usr", X "/", X ".", X "/", X ".", X ".", X"/the/lion/is/the/king/of/the/jungle/and/this/is/more/than/64/chars", X"/the/lion/is/the/king/of/the/jungle/and/this/is/much/longer/than/the/other", X}; X X/* X** The test must interact with malloc in its own right to show up the bug in X** version 1.4 (where the free released the argument s instead of s_str). X*/ Xint main(void) X{ X const char **p1; X const char **p2; X char *p; X X for (p1 = files, p2 = dirs; p1 < files + DIM(files); p1++, p2++) X { X printf("File = %-10s Dirname = %-10s Correct = %s\n", *p1, dirname(*p1), X (strcmp(dirname(*p1), *p2) == 0) ? "Yes" : "No"); X p = malloc(32); X strncpy(p, "complete and utter garbage", 32); X } X X#if 0 X { X char buff[512]; X printf("Name? "); X while (fgets(buff, sizeof(buff), stdin) != NIL(char *)) X { X buff[strlen(buff) - 1] = '\0'; X printf("Full Name: %s\nDirectory: %s\n", buff, dirname(buff)); X printf("Name? "); X } X putchar('\n'); X } X#endif /* 0 */ X X return(0); X} X X#endif /* TEST */ SHAR-EOF chmod 444 dirname.c if [ `wc -c fl.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: fl.c,v $ X@(#)Version: $Revision: 1.9 $ X@(#)Last changed: $Date: 1997/02/04 14:54:34 $ X@(#)Purpose: Variation on the theme of LS(1) X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1991,1996-97 X*/ X X/*TABSTOP=4*/ X X/* X** This program is a variation on the theme of LS(1). X** Essentially, it does the same job, but the attributes which are printed X** can be selected individually, and can be ordered in any required manner. X** Also, things like dates are handled more systematically. X** X** One major change is that the program does no sorting itself. X** If you need sorted output, use SORT(1). This may seem unfriendly, but X** the program is intended for use in scripts, and people who can write X** shell scripts can also use SORT(1). X** X** Options: X** -A access time (number) X** -C change time (number) X** -D list directory, not elements of directory X** -F date/time format (for strftime(3)) X** -G gid of group X** -L follow symbolic links (use stat(2) in place of lstat(2)) X** -M modification time (number) X** -N absolute name X** -O uid of owner X** -P permissions (octal, including type) X** -Q permissions (octal, excluding type) X** -R list recursively X** -S print file size in 512-byte blocks (or maj,min for specials) X** -K name symbolic link points to (result of readlink(2)) X** -a access time (formatted date) X** -c change time (formatted date) X** -g name of group X** -i inode X** -l link count X** -m modification time (formatted date) X** -n name as specified X** -o name of owner X** -p permissions (as in ls -l, including type) X** -q permissions (as in ls -l, excluding type) X** -s size in bytes (or maj,min for specials) X** -t type (single letter) X** X** The comments provided below provide some provenance for this software. X** The details of the changes are irrelevant to this program. X*/ X X/* X*************************************************** X** ls - list files Author: Peter Housel ** X*************************************************** X** X** From: ast@cs.vu.nl (Andy Tanenbaum) X** Newsgroups: comp.os.minix X** Message-ID: <5068@ast.cs.vu.nl> X** Date: 11 Jan 90 23:30:24 GMT X** Sender: ast@cs.vu.nl X** Organization: Fac. Wiskunde & Informatica, VU, Amsterdam X** X** Introduction. X** This file is part of ls for Minix. It was written in the spring X** of 1989 by Peter S. Housel. This program is in the public domain and may X** be redistributed without restriction. As such, no warranty of any kind X** is provided. X** X** The following changes to the program have been made: X** Version 1.1 - removed references to -q option, added |ONECOLUMN| X** and other compile-time options. X** X** Ls is a version of standard Minix directory listing program. Because X** it is used so often used, it should be as fast as possible. It should be X** somewhat "featureful" (Rob Pike nonwithstanding), but not in a way X** that interferes with its use as a "software tool." X*/ X X#define major(x) ((x>>8) & 0377) X#define minor(x) (x & 0377) X#define NIL(x) ((x)0) X#define BLOCK_CHAR_DEV(mode) ((mode&S_IFMT)==S_IFCHR||(mode&S_IFMT)==S_IFBLK) X X#ifndef NO_SYMLINKS X/* To get lstat from and readlink from on Solaris 2.4 */ X#define __EXTENSIONS__ X#endif X X#define MAIN_PROGRAM X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include "getopt.h" X#include "stderr.h" X#include "clnpath.h" X X/* X** DOTDIR determines whether or not a given name is one of the X** special directory files "." or "..". X*/ X#define DOTDIR(s) (s[0]=='.'&&(s[1]=='\0'||(s[1]=='.'&&s[2]=='\0'))) X X#define VALID_FLAGS "ACDF:GKLMNOPQRSTVXacgilmnopqst" Xstatic const char usestr[] = X "[-ACDGKLMNOPQRSTVXacgilmnopqst][-F dateformat] [file ...]"; X Xstatic int flags_D; /* Print directory, not contents of directory */ Xstatic int flags_L; /* Follow symbolic links */ Xstatic int flags_R; /* Print directories recursively */ Xstatic int flags_X; /* Print all files in directories */ Xstatic int flags_n; /* Either -n or -N specified */ Xstatic int flags_x; /* Internal flag to print all files */ X X/* X** By default, all dates are printed in the format 1991-08-04 11:30:21 X*/ X#ifndef DEF_DATETIME X#define DEF_DATETIME "%Y-%m-%d %H:%M:%S" X#endif Xstatic char *date_time = DEF_DATETIME; X X/* X** We have to store the output in a template string. X** This one is ridiculously large, but we won't check on its bounds! X*/ Xstatic char template[BUFSIZ]; X Xstatic char *absdotname(char *filename); Xstatic char *absname(char *filename); Xstatic char *anydotname(char *filename, char *(*function)(char *)); Xstatic char *groupname(int gid); Xstatic char *lsperms(int mode); Xstatic char *ownername(int uid); Xstatic char *reldotname(char *filename); Xstatic char *relname(char *filename); Xstatic char *typename(int mode); Xstatic int typeletter(int mode); Xstatic long nblocks(long size); Xstatic void filelist(char *st_name, char *pr_name, int level); Xstatic void listone(char *name, struct stat *sb, int dotdir); Xstatic void prdate(time_t filetime); X Xextern char *basename(char *filename); Xextern char *dirname(char *filename); Xextern char *vstrcpy(char *s0, int n, char *s1, ...); Xextern int getpwd(const char *buff, size_t len); X X#ifndef lint Xstatic const char sccs[] = "@(#)$Id: fl.c,v 1.9 1997/02/04 14:54:34 johnl Exp $"; X#endif X Xint main(int argc, char **argv) X{ X int c; /* option character */ X char *s; /* pointer into template */ X X setarg0(argv[0]); X opterr = 0; X X s = template; X while ((c = getopt(argc, argv, VALID_FLAGS)) != EOF) X { X switch (c) X { X case 'n': X case 'N': X flags_n = 1; X /*DROPTHROUGH*/ X case 'A': X case 'C': X case 'G': X case 'K': X case 'M': X case 'O': X case 'P': X case 'Q': X case 'S': X case 'T': X case 'a': X case 'c': X case 'g': X case 'i': X case 'l': X case 'm': X case 'o': X case 'p': X case 'q': X case 's': X case 't': X *s++ = c; X break; X X case 'L': X flags_L = 1; X break; X case 'R': X flags_R = 1; X break; X case 'D': X flags_D = 1; X break; X case 'X': /* Print all entries */ X flags_X = 1; X break; X case 'F': X date_time = optarg; X break; X case 'V': X version("FL", "$Revision: 1.9 $ ($Date: 1997/02/04 14:54:34 $)"); X break; X case '?': X usage(usestr); X break; X } X } X X /* Check that name is specified. If not, add it at the end */ X if (flags_n == 0) X *s++ = 'n'; X X *s = '\0'; /* Terminate template */ X X if (geteuid() == 0 && !flags_X) X flags_x = 1; X X argc -= optind - 1; X argv += optind - 1; X X /* X ** Process each named argument in turn. X ** If no arguments named, use ".", the current directory. X */ X if (argc <= 1) X filelist(".", ".", 0); X else X { X while (*++argv != NIL(char *)) X filelist(*argv, *argv, 0); X } X X return (0); X} X X/* X** The filelist() function is the "heart" of this program. X** It uses listone() to print the details of a file, X** and if the file is a directory, invokes itself recursively X** to list the files in the sub-directory. This means that there X** is a limit to the depth of hierarchy which it will traverse, X** imposed by the number of files which it can have open. X** X** To simulate ls as closely as possible, the three arguments are necessary. X** If the argument on the command line is a directory, we list the contents X** of that directory, unless the -X flag was specified. X*/ Xstatic void filelist( Xchar *st_name, /* Name for stat(3) */ Xchar *pr_name, /* Name for printing */ Xint level) /* level == 0 => command-line argument */ X{ X DIR *dirp; X struct dirent *dp; X char buffer[BUFSIZ]; X char *file; X struct stat sb; X int isdir; X X#ifndef NO_SYMLINKS X if (flags_L == 0) X { X if (lstat(st_name, &sb) < 0) X { X remark2("can't lstat", st_name); X return; X } X } X else X#endif /* NO_SYMLINKS */ X if (stat(st_name, &sb) < 0) X { X remark2("can't stat", st_name); X return; X } X X isdir = (sb.st_mode & S_IFMT) == S_IFDIR; X if (level > 0 || !isdir || flags_D != 0) X listone(pr_name, &sb, 0); X X if (isdir && (flags_R || (level == 0 && flags_D == 0))) X { X if ((dirp = opendir(st_name)) == NULL) X { X remark2("can't open directory", st_name); X return; X } X while ((dp = readdir(dirp)) != NULL) X { X /* Skip files starting with . unless requested or root */ X if (dp->d_name[0] == '.' && !(flags_x || flags_X)) X continue; X else if (DOTDIR(dp->d_name)) X { X if (flags_X || flags_x) X { X vstrcpy(buffer, 3, pr_name, "/", dp->d_name); X if (stat(buffer, &sb) < 0) X remark2("can't stat", buffer); X else X listone(buffer, &sb, 1); X } X continue; X } X /* VSTRCPY -- use is not efficient: assign prefix out of loop. */ X vstrcpy(buffer, 3, st_name, "/", dp->d_name); X if (level > 0) X file = buffer; X else X file = dp->d_name; X filelist(buffer, file, level + 1); X } X (void) closedir(dirp); X } X} X X/* X** linkname() returns a pointer to the file pointed to by a symbolic link, X** or an empty string. X*/ X Xstatic char *linkname(char *name) X{ X static char buffer[BUFSIZ]; X size_t nchars; X X strcpy(buffer, "-> "); X#ifndef NO_SYMLINKS X if ((nchars = readlink(name, &buffer[3], sizeof(buffer)-3)) < 0) X buffer[2] = '\0'; X else X buffer[3+nchars] = '\0'; X#else X buffer[2] = '\0'; X#endif /* NOSYMLINKS */ X return(buffer); X} X X/* X** listone() prints the data for the named file using the template. X** Each field is printed as requested, separated by blanks. X*/ Xstatic void listone(char *name, struct stat *sb, int dotdir) X{ X register char *s; X register char c; X char pad = '\0'; X X s = template; X while ((c = *s++) != '\0') X { X if (pad != '\0') X putchar(pad); X pad = ' '; X switch (c) X { X case 'a': X prdate(sb->st_atime); X break; X case 'c': X prdate(sb->st_ctime); X break; X case 'm': X prdate(sb->st_mtime); X break; X case 'A': X printf("%9lu", (unsigned long)sb->st_atime); X break; X case 'C': X printf("%9lu", (unsigned long)sb->st_ctime); X break; X case 'K': X printf("%s", linkname(name)); X break; X case 'M': X printf("%9lu", (unsigned long)sb->st_mtime); X break; X case 'i': X printf("%5lu", (unsigned long)sb->st_ino); X break; X case 'S': X if (BLOCK_CHAR_DEV(sb->st_mode)) X printf("%3ld,%-3ld", major(sb->st_rdev), minor(sb->st_rdev)); X else X printf("%7ld", nblocks(sb->st_size)); X break; X case 's': X if (BLOCK_CHAR_DEV(sb->st_mode)) X printf("%3ld,%-3ld", major(sb->st_rdev), minor(sb->st_rdev)); X else X printf("%7ld", sb->st_size); X break; X case 'l': X printf("%3ld", sb->st_nlink); X break; X case 'G': X printf("%5ld", (long)sb->st_gid); X break; X case 'O': X printf("%5ld", (long)sb->st_uid); X break; X case 'g': X printf("%8s", groupname(sb->st_gid)); X break; X case 'o': X printf("%8s", ownername(sb->st_uid)); X break; X case 'n': X if (dotdir) X printf("%s", reldotname(name)); X else X printf("%s", relname(name)); X break; X case 'N': X if (dotdir) X printf("%s", absdotname(name)); X else X printf("%s", absname(name)); X break; X case 't': X printf("%c", typeletter(sb->st_mode)); X break; X case 'T': X printf("%-9s", typename(sb->st_mode)); X break; X case 'p': X printf("%s", lsperms(sb->st_mode)); X break; X case 'q': X printf("%s", lsperms(sb->st_mode) + 1); X break; X case 'P': X printf("%07lo", (unsigned long)sb->st_mode); X break; X case 'Q': X printf("%04lo", (unsigned long)(sb->st_mode & ~S_IFMT)); X break; X } X } X putchar('\n'); X} X X/* X** Convert a mode field into "ls -l" type perms field. X*/ Xstatic char *lsperms(int mode) X{ X static char *rwx[] = {"---", "--x", "-w-", "-wx", X "r--", "r-x", "rw-", "rwx"}; X static char bits[11]; X X bits[0] = typeletter(mode); X strcpy(&bits[1], rwx[(mode >> 6) & 7]); X strcpy(&bits[4], rwx[(mode >> 3) & 7]); X strcpy(&bits[7], rwx[(mode & 7)]); X if (mode & S_ISUID) X bits[3] = (mode & 0100) ? 's' : 'S'; X if (mode & S_ISGID) X bits[6] = (mode & 0010) ? 's' : 'l'; X if (mode & S_ISVTX) X bits[9] = (mode & 0100) ? 't' : 'T'; X bits[10] = '\0'; X return (bits); X} X Xstatic char unknown[] = "unknown"; Xstatic char *type_name[] = X{ X unknown, X "fifo", X "character", X "block", X unknown, X "directory", X unknown, X unknown, X "file", X unknown, X unknown, X unknown, X unknown, X unknown, X unknown, X unknown X}; X Xstatic char *typename(int mode) X{ X mode = (mode >> 12) & 0xF; X return (type_name[mode]); X} X Xstatic int typeletter(int mode) X{ X char c; X X switch (mode & S_IFMT) X { X case S_IFDIR: X c = 'd'; X break; X case S_IFBLK: X c = 'b'; X break; X case S_IFCHR: X c = 'c'; X break; X#ifdef S_IFIFO X case S_IFIFO: X c = 'p'; X break; X#endif /* S_IFIFO */ X#ifdef S_IFLNK X case S_IFLNK: X c = 'l'; X break; X#endif /* S_IFLNK */ X#ifdef S_ISOCK X case S_ISOCK: X c = 's'; X break; X#endif /* S_ISOCK */ X default: X c = '-'; X break; X } X return (c); X} X X/* X** User and group id's. X** ownername() and groupname() are used to translate user and group X** id's to names. The last id translated is cached. X*/ X Xstatic char *ownername(int uid) X{ X static int ouid = -1; X static char uname[16]; X struct passwd *pw; X X if (uid == ouid) X return uname; X X if ((pw = getpwuid(uid)) == NULL) X sprintf(uname, "%d", uid); X else X strcpy(uname, pw->pw_name); X X return uname; X} X Xstatic char *groupname(int gid) X{ X static int ogid = -1; X static char gname[16]; X struct group *gr; X X if (gid == ogid) X return gname; X X if ((gr = getgrgid(gid)) == NULL) X sprintf(gname, "%d", gid); X else X strcpy(gname, gr->gr_name); X X return gname; X} X X/* X** Date and time. prdate prints the specified time in the format specified X** by date_time (set with the -F option) using the function strftime(3). X*/ X Xstatic void prdate(time_t filetime) X{ X struct tm *timep; X char buffer[BUFSIZ]; X X timep = localtime(&filetime); X strftime(buffer, sizeof(buffer), date_time, timep); X X printf("%s", buffer); X} X X#define BLOCK_SIZE 512 /* Reporting blocks */ X#define PHYS_BLOCK_SIZE (BLOCK_SIZE*2) /* Blocks on disc */ X#define N_DIRECT_PER_INODE 10 /* 10 direct blocks in inode */ X#define N_POINTERS_PER_BLOCK (PHYS_BLOCK_SIZE/sizeof(long)) X#define REPORT_BLOCKS(x) ((x)*(PHYS_BLOCK_SIZE/BLOCK_SIZE)) X X/* Convert file length to blocks, including indirect blocks. */ Xstatic long nblocks(long size) X{ X long blocks; X long fileb; X X fileb = (size + (long) PHYS_BLOCK_SIZE - 1) / PHYS_BLOCK_SIZE; X blocks = fileb; X if ((fileb -= N_DIRECT_PER_INODE) <= 0) X return (REPORT_BLOCKS(blocks)); X X fileb = (fileb + N_POINTERS_PER_BLOCK - 1) / N_POINTERS_PER_BLOCK; X blocks += fileb; /* Indirect blocks */ X if (--fileb <= 0) X return (REPORT_BLOCKS(blocks)); X X fileb = (fileb + N_POINTERS_PER_BLOCK - 1) / N_POINTERS_PER_BLOCK; X blocks += fileb; /* Double Indirect blocks */ X if (--fileb <= 0) X return (REPORT_BLOCKS(blocks)); X X blocks++; /* Triple indirect block */ X X return (REPORT_BLOCKS(blocks)); X} X X/* X** Return relative pathname of a file X*/ Xstatic char *relname(char *name) X{ X clnpath(name); X return (name); X} X X/* X** Return absolute pathname of a file X*/ Xstatic char *absname(char *name) X{ X static char buffer[BUFSIZ]; X static char pwd[BUFSIZ]; X X if (*name != '/') X { X if (pwd[0] == '\0') X getpwd(pwd, sizeof(pwd)); X vstrcpy(buffer, 3, pwd, "/", name); X } X else X strcpy(buffer, name); X clnpath(buffer); X X return (buffer); X} X X/* X** Return relative pathname of file ending with . or .. X*/ Xstatic char *reldotname(char *name) X{ X return(anydotname(name, relname)); X} X X/* X** Return absolute pathname of file ending with . or .. X*/ Xstatic char *absdotname(char *name) X{ X return(anydotname(name, absname)); X} X X/* X** Return pathname of file ending with /. or xyz/.. X*/ Xstatic char *anydotname(char *name, char *(*function)(char *)) X{ X char *cp1; X char *cp2; X int dotdot; X static char buffer[BUFSIZ]; X X dotdot = strcmp(basename(name), "..") == 0; X cp1 = dirname(name); X cp2 = (*function)(cp1); X X if (!DOTDIR(cp2)) X (void)vstrcpy(buffer, 2, cp2, (dotdot ? "/.." : "/.")); X else X strcpy(buffer, (dotdot ? ".." : ".")); X return (buffer); X} SHAR-EOF chmod 444 fl.c if [ `wc -c getopt.h <<'SHAR-EOF' X/* X@(#)File: $RCSfile: getopt.h,v $ X@(#)Version: $Revision: 1.8 $ X@(#)Last changed: $Date: 1997/05/07 10:17:05 $ X@(#)Purpose: Declarations for GETOPT(3) and GETSUBOPT(3) X@(#)Author: J Leffler X@(#)Copyright: JLSS (C) 1992-93,1996-97 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X#ifndef GETOPT_H X#define GETOPT_H X X/* X** GNU getopt provides facilities not available in standard getopt. X** Specifically, it will reorder all option arguments before all non-option X** arguments, and it can also handle optional arguments (must be attached X** to option letter) and it can be told to return all arguments in order, X** with a value of '\0' indicating a file option... X** It has a different interface from standard getopt -- the second argument X** is not const. X*/ X Xextern int optopt; Xextern int opterr; Xextern int optind; Xextern char *optarg; X Xextern int getopt(int argc, char *const*argv, const char *opts); Xextern int getsubopt(char **opt, char *const*names, char **value); Xextern int gnu_getopt(int argc, char **argv, const char *opts); X X#ifndef GETOPT X#ifdef USE_GNU_GETOPT X#define GETOPT(argc, argv, opts) gnu_getopt(argc, argv, opts) X#else X#define GETOPT(argc, argv, opts) getopt(argc, argv, opts) X#endif /* USE_GNU_GETOPT */ X#endif /* GETOPT */ X X#endif /* GETOPT_H */ SHAR-EOF chmod 444 getopt.h if [ `wc -c getpwd.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: getpwd.c,v $ X@(#)Version: $Revision: 1.7 $ X@(#)Last changed: $Date: 1991/12/22 14:13:15 $ X@(#)Purpose: Evaluate present working directory X@(#)Author: J Leffler X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X/* -- Include Files */ X X#include X#include X#include X X#if defined(_POSIX_SOURCE) || defined(USG_DIRENT) X#include "dirent.h" X#elif defined(BSD_DIRENT) X#include X#define dirent direct X#else XWhat type of directory handling do you have? X#endif X X/* -- Constant Definitions */ X X#define PUBLIC X#define PRIVATE static X#define RECURSIVE X#define READONLY 0 X#define DIRSIZ 256 X X/* -- Macro Definitions */ X X#define NIL(x) ((x)0) X X/* -- Type Definitions */ X Xtypedef struct stat Stat; X X/* -- Declarations */ X Xstatic Stat root; X X#ifndef lint Xstatic char sccs[] = "$Id: getpwd.c,v 1.7 1991/12/22 14:13:15 jl Exp $"; X#endif X X/* -- Routine: getpwd */ X XPUBLIC char *getpwd(pwd, plen) X Xchar *pwd; /* In: buffer for name of current directory */ Xint plen; /* In: length of buffer */ X X/* X Purpose: Evaluate name of current directory X X Maintenance Log X --------------- X 10/11/86 JL Original version stabilised X 25/09/88 JL Short circuit if pwd = / X 25/09/90 JL Revise interface; check length X X Known Bugs X ---------- X 1. Uses chdir() and could possibly get lost in some other directory X X*/ X{ X int status; X Stat here; X X if (pwd == NIL(char *)) X pwd = malloc(plen); X if (pwd == NIL(char *)) X return (pwd); X X if (stat("/", &root) || stat(".", &here)) X status = -1; X else if (root.st_ino == here.st_ino && root.st_dev == here.st_dev) X { X strcpy(pwd, "/"); X status = 0; X } X else X status = finddir(here.st_ino, here.st_dev, pwd, plen); X if (status != 0) X pwd = NIL(char *); X return (pwd); X} X X/* -- Routine: inode_number */ X XPRIVATE ino_t inode_number(path, name) Xchar *path; Xchar *name; X{ X ino_t inode; X Stat st; X char buff[DIRSIZ + 6]; X X strcpy(buff, path); X strcat(buff, "/"); X strcat(buff, name); X if (stat(buff, &st)) X inode = 0; X else X inode = st.st_ino; X return(inode); X} X X/* -- Routine: finddir */ X XPRIVATE RECURSIVE int finddir(inode, device, path, plen) X Xino_t inode; /* In: Inode of current directory */ Xdev_t device; /* In: Device for current directory */ Xchar *path; /* Out: pathname of current directory */ Xint plen; /* In: Length of buffer for pathname */ X X/* X Purpose: Find name of present working directory X X Maintenance Log X --------------- X 10/11/86 JL Original version stabilised X 25/09/88 JL Rewritten to use opendir/readdir/closedir X 25/09/90 JL Modified to pay attention to length X X*/ X{ X register char *src; X register char *dst; X char *end; X DIR *dp; X struct dirent *d_entry; X Stat dotdot; X Stat file; X ino_t d_inode; X int status; X static char name[] = "../123456789.abcd"; X char d_name[DIRSIZ + 1]; X X if (stat("..", &dotdot) || (dp = opendir("..")) == NIL(DIR *)) X return(-1); X /* Skip over "." and ".." */ X if ((d_entry = readdir(dp)) == NIL(struct dirent *) || X (d_entry = readdir(dp)) == NIL(struct dirent *)) X { X /* Should never happen */ X closedir(dp); X return(-1); X } X X status = 1; X while (status) X { X if ((d_entry = readdir(dp)) == NIL(struct dirent *)) X { X /* Got to end of directory without finding what we wanted */ X /* Probably a corrupt file system */ X closedir(dp); X return(-1); X } X else if ((d_inode = inode_number("..", d_entry->d_name)) != 0 && X (dotdot.st_dev != device)) X { X /* Mounted file system */ X dst = &name[3]; X src = d_entry->d_name; X while (*dst++ = *src++) X ; X if (stat(name, &file)) X { X /* Can't stat this file */ X continue; X } X status = (file.st_ino != inode || file.st_dev != device); X } X else X { X /* Ordinary directory hierarchy */ X status = (d_inode != inode); X } X } X strncpy(d_name, d_entry->d_name, DIRSIZ); X closedir(dp); X X /** X ** NB: we have closed the directory we are reading before we move out of it. X ** This means that we should only be using one extra file descriptor. X ** It also means that the space d_entry points to is now invalid. X */ X src = d_name; X dst = path; X end = path + plen; X if (dotdot.st_ino == root.st_ino && dotdot.st_dev == root.st_dev) X { X /* Found root */ X status = 0; X if (dst < end) X *dst++ = '/'; X while (dst < end && (*dst++ = *src++) != '\0') X ; X } X else if (chdir("..")) X status = -1; X else X { X /* RECURSE */ X status = finddir(dotdot.st_ino, dotdot.st_dev, path, plen); X (void)chdir(d_name); /* We've been here before */ X if (status == 0) X { X while (*dst) X dst++; X if (dst < end) X *dst++ = '/'; X while (dst < end && (*dst++ = *src++) != '\0') X ; X } X } X X if (dst >= end) X status = -1; X return(status); X} X X#ifdef TEST X/* -- Routine: main */ X XPUBLIC int main() X X/* X Purpose: Test getpwd() X X Maintenance Log X --------------- X 10/11/86 JL Original version stabilised X 25/09/90 JL Modified interface; use GETCWD to check result X X*/ X{ X char pwd[512]; X int pwd_len; X extern char *getcwd(); X X if (getpwd(pwd, sizeof(pwd)) == NIL(char *)) X printf("GETPWD failed to evaluate pwd\n"); X else X printf("GETPWD: %s\n", pwd); X if (getcwd(pwd, sizeof(pwd)) == NIL(char *)) X printf("GETCWD failed to evaluate pwd\n"); X else X printf("GETCWD: %s\n", pwd); X pwd_len = strlen(pwd); X if (getpwd(pwd, pwd_len - 1) == NIL(char *)) X printf("GETPWD failed to evaluate pwd (correct!)\n"); X else X printf("GETPWD: %s (but should have failed!!!)\n", pwd); X return(0); X} X X#endif SHAR-EOF chmod 444 getpwd.c if [ `wc -c informix.1 <<'SHAR-EOF' X'\" @(#)$Id: informix.1,v 1.2 1993/06/13 13:06:47 jl Exp $ X'\" @(#)Manual Page for: Informix Cron Scripts X.ds fC "Version: $Revision: 1.2 $ ($Date: 1993/06/13 13:06:47 $) X.TH INFORMIX 1J "JLSS Informix Tools" X.SH NAME Xinformix \(em cron scripts for informix X.SH DESCRIPTION XThe file \*ccrontab\*d is the suggested \fIcrontab(1)\fP entry Xfor user \*cinformix\*d. XAs supplied, it assumes \*c/usr/informix\*d is the correct value Xfor \s-2INFORMIXDIR\s0. XIf your system supports symbolic links, \*c/usr/informix\*d Xshould be a symbolic link to where the software is really Xinstalled, whether that is also in the \*c/usr\*d file system X(such as \*c/usr/informix4.10\*d) or somewhere on another file Xsystem altogether, such as \*c/home/informix5.01\*d. X.P XThe scripts \*cixhourly\*d, \*cixdaily\*d, \*cixweekly\*d are Xscheduled to be run by \fIcron(1M)\fP each hour, each day, each Xweek, and are assumed to be in \*c/usr/informix/bin\*d. XBy default, the hourly script is run at one minute past the hour, Xthe daily script is run at 00:37, and the weekly script is run on XSunday at 12:03. XThese scripts must set \s-2INFORMIXDIR\s0 if it is not X\*c/usr/informix\*d; the other scripts assume that it is set or Xcan be defaulted. X.P XThe \*cixhourly\*d script runs a series of other operations: X\*cixstats\*d, \*cixwarn\*d, \*cunixwarn\*d, \*cixmsgpath\*d Xand \*ctbstat\ -z\*d. X.P XThe \*cixdaily\*d script runs a couple of operations: X\*cixcomp\*d and \*cixcheck\*d. X.P XThe \*cixweekly\*d script runs a couple of operations: X\*cixrestart\*d and \*cixclean\*d. X.SH "ASSUMPTIONS" XIt is assumed that there is a directory \*c$INFORMIXDIR/log\*d Xwhich is used to store the various log files, as indicated by the X\s-2MSGPATH\s0 and \s-2CONSOLE\s0 parameters in \s-2TBCONFIG\s0. XIt will also contain a series of sub-directories with names such Xas \*c1993.06.13\*d for holding various records for the relevant Xdate. XThe \*c$INFORMIXDIR/log\*d directory is referred to as X\s-2LOGDIR\s0, and \*c$INFORMIXDIR/log/1993.06.13\*d is referred Xto as \s-2LOGSUBDIR\s0 in this manual page. X.P XIt is assumed that the commands described here are installed in X\*c$INFORMIXDIR/bin\*d, so only that directory has to be added to Xthe path supplied by \fIcron\fP. XAn alternative is to keep these tools in \*c$INFORMIXDIR/adm\*d. X.P XIt is assumed that the data files (sed scripts) used by \*cixcheck\*d X(see below) are either in \*c$INFORMIXDIR/etc\*d or \*c$INFORMIXDIR/adm\*d. X(For ease of testing, \*cixcheck\*d looks in the current Xdirectory before looking in the standard directories). X.P XIt is assumed that mail sent to user \*cinformix\*d is actually Xforwarded to one or more people who will (and can) respond when necessary. X'\" X'\" ----------------------------------------------------- X'\" X.SH "DETAILED COMMANDS" XThe \*cixstats\*d script saves the output from \*ctbstat\ -plu\*d Xand \*cps\ -ef\*d in a file in \s-2LOGSUBDIR\s0. XThe name of the file will be of the form \*cts.12:15:37\*d, Xindicating the time when the stats were recorded. X.P XThe \*cixwarn\*d script analyses a few key indicators from X\*ctbstat\*d and sends mail to user \*cinformix\*d if they are Xnot satisfactory. XThe statistics are non-zero foreground writes, read cache Xefficiency below 90%, write cache efficiency below 70% and write Xactivity greater than 5% of read activity, overflows on tables, Xlocks, users or buffers. X.P XThe \*cunixwarn\*d script sends \*cinformix\*d a list of the Xprocesses which have used more than 10:00 minutes of CPU time. XThese are candidate runaway processes which may need to be Xcleaned up manually. X.P XThe \*cixmsgpath\*d script monitors the new messages in the X\s-2MSGPATH\s0 file and reports on any unexpected messages by Xsending them to user \*cinformix\*d. XThe expected messages are `Checkpoint Completed', `Logical Log XComplete', and `Logical Log Backed Up' messages. XMessages that the `Logical Log Files are Full' are handled Xseparately from the other unexpected messages. XThe date stamps will not trigger the sending of mail. XIt uses the file \*cmsgpath\*d in \s-2LOGDIR\s0 to record how far Xit has got through the \s-2MSGPATH\s0 file, so that each problem Xis reported only once. XNote, \*cixmsgpath\*d will always report on the startup messages Xand changes in mode, and on archive events. XYou would need to extend the filter conditions to suppress these. X.P XThe \*cixcomp\*d script compresses all non-compressed files in Xany sub-directory of \s-2LOGDIR\s0. XThis minimises the volume of data held. X.P XThe \*cixcheck\*d script is a simple interface to \fItbcheck\fP Xwhich reports (by mail to user \*cinformix\*d) any untoward Xproblems in the OnLine system. XIt can be run with or without arguments. XWithout arguments, it invokes itself (many times) with Xappropriate sets of arguments to check the entire OnLine system Xfor sanity. XThis means it runs \fItbcheck\fP with the options `\*c-cr\*d' and X`\*c-ce\*d' to check the reserved pages and the extents, and then Xuses the command \*cdbnames\*d to run \fItbcheck\fP with the Xoptions `\*c-cc\*d', `\*c-cD\*d', and `\*c-cI\*d' for each database. XThere is a set of \fIsed(1)\fP scripts which are used to filter Xout the expected message lines from the output of \fItbcheck\fP. X.P XThe \*cixrestart\*d script shuts down OnLine if it is not already Xshutdown, runs \*cixrstmsg\*d to create an empty message file, Xand then brings OnLine back up in multi-user mode. X.P XThe \*cixclean\*d script removes all files more than 30 days old Xfrom under \s-2LOGDIR\s0, and cleans up any empty directories. XIt also runs \*cixcomp\*d to compress any files which aren't yet Xcompressed. XNB: any files which should be preserved must not be kept under X\s-2LOGDIR\s0 as all the sub-directories under there are Xregularly cleaned out and empty directories are removed. X.P XThe \*cixrstmsg\*d script moves the existing \s-2MSGPATH\s0 file Xunder \s-2LOGSUBDIR\s0, renaming it to something like X\*clog.12:35:23\*d to indicate when it was saved. XIt also resets the line number in the \*cmsgpath\*d in \s-2LOGDIR\s0 Xso that \*cixmsgpath\*d will continue to report correctly. X.P XThe \*cixperms\*d script checks the permissions of the files and Xdirectories under \*c$INFORMIXDIR\*d. XIt does so by combining the installed file lists from X\*c$INFORMIXDIR/etc/*files\*d, stripping out duplicate entries X(and comments and other unwanted lines), and then checking that Xeach of the listed files which exists has the correct permissions. XIt is possible to add custom files to the list by creating an Xextra file (or extra files) in \*c$INFORMIXDIR/etc\*d whose name Xends in \*cfiles\*d; these should be in the same general format Xas files such as \*conlinefiles\*d, and will be used in the same Xway as the standard distribution files. XMissing files are not flagged, which means, for example, that the Xinstall scripts can be moved from \*c$INFORMIXDIR\*d into X\*c$INFORMIXDIR/etc\*d without causing errors to be reported. XIt uses the command \*cfl\*d to establish the actual owner, group Xand permissions of each file for comparison with the official Xvalues from the permissions files. X.P XThe \*cixcrontab\*d script is a simple device to ensure that only Xuser \*cinformix\*d sets the \fIcrontab\fP entry for \*cinformix\*d, Xthus preventing other users from accidentally clobbering their Xown \fIcrontab\fP entries. X.P XThe \*cixmail\*d script conditionally sends mail to user X\*cinformix\*d. XIt cleans up the mail, removing trailing blanks and duplicate Xlines, and only actually sends mail if there is a non-empty Xmessage to send. XIt is crucial to the operability of the automatic system, because Xthe watch-dog must not bark so often that the warnings are Xignored when they are important. XThis requires that the users receiving mail are only notified Xwhen something has gone wrong. XThe other scripts are careful only to send mail when there is Xtrouble, and \*cixmail\*d backs this up by making it simple to Xfeed the output to the mailer knowing that no message will be Xsent unless there is some information to send. X.P XThe \*cixconfig\*d script is used to extract a parameter from the X\s-2TBCONFIG\s0 file. XIt is called with the name of the parameter to be returned, Xoptionally followed by the name of the configuration file which Xmay be absolute or relative. XIt echoes the value of the parameter on standard output. X'\" X'\" ----------------------------------------------------- X'\" X.SH "VARIATIONS" XThe default system assumes that there is a single OnLine system Xon the machine and that \s-2TBCONFIG\s0 should be set to X\*ctbconfig\*d. XThe scripts run by \fIcron\fP should be upgraded if either Xassumption is false, setting \s-2TBCONFIG\s0 to the correct value Xor values and running the commands inside a loop. X.SH "BUGS" XSurely not. XProbably \(em let me know, please. X.SH AUTHOR XJonathan Leffler X.br XInformix Software X.br X13th June 1993 SHAR-EOF chmod 444 informix.1 if [ `wc -c instfile.sh <<'SHAR-EOF' X: "$Id: instfile.sh,v 1.2 1992/05/10 17:43:36 jl Exp $" X# X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# X# Install file X# Put in named directory belonging to owner, group and with permissions set X Xcase $# in X5) if [ ! -f $1 ] X then X echo "$0: $1 not found" X exit 1 X fi X dname=$2/`dirname $1` X if [ ! -d $dname ] X then X echo "$0: $dname is not a directory" X exit 1 X fi X mv $1 tmp.$$ # Save new file (just in case it is in correct place) X rm -f $2/$1 # Remove existing destination file X mv tmp.$$ $2/$1 # Store new file in correct place X set -e X chmod $5 $2/$1 X chgrp $4 $2/$1 X chown $3 $2/$1 X ;; X*) echo "Usage: $0 file dir owner group perms" >&2 X exit 1;; Xesac SHAR-EOF chmod 444 instfile.sh if [ `wc -c ius.rc <<'SHAR-EOF' X: "@(#)$Id: ius.rc,v 1.1 1997/05/12 11:38:53 johnl Exp $" X# X# Control script for Informix-Universal Server X# X# * Edit INFORMIXDIR, INFORMIXSERVER and ONCONFIG to match your system. X# * Install under /etc, possibly in /etc/init.d with links in /etc/rcN.d, X# or possibly listing it in /etc/inittab. X XINFORMIXDIR=/usr/informix Xexport INFORMIXDIR XPATH=$INFORMIXDIR/bin:$PATH Xexport PATH XINFORMIXSERVER=ius Xexport INFORMIXSERVER XINFORMIXSQLHOSTS=$INFORMIXDIR/etc/sqlhosts Xexport INFORMIXSQLHOSTS XONCONFIG=onconfig.ius Xexport ONCONFIG X Xcase "$1" in Xstart) X echo "Starting Informix-Universal Server ($INFORMIXSERVER)" X onstat -V X oninit || echo "*** FAILED TO START $INFORMIXSERVER ***" X ;; Xstop) X if onstat -p > /dev/null X then X echo "Stopping Informix-Universal Server ($INFORMIXSERVER)" X onmode -ky || echo "*** FAILED TO STOP $INFORMIXSERVER ***" X else X echo "Informix-Universal Server ($INFORMIXSERVER) not running" X fi X ;; X*) X echo "Usage: $0 { start | stop }" 1>&2 X exit 1 X ;; Xesac X SHAR-EOF chmod 444 ius.rc if [ `wc -c ixadm.bod <<'SHAR-EOF' X# @(#)$Id: ixadm.bod,v 1.4 1997/05/12 11:42:31 johnl Exp $ X# @(#)IXADM -- JLSS Informix Adminstration Tools X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# @(#)Definitive list of files -- Binary-Only Distribution X# X# -- The Distributed file column contains the name of a file in X# the distribution directory. X# -- The Compiled file column contains the name of the file in the X# working directory. X# X# -- Note that it is possible to rename files using this mechanism. X# X# -- Note that it is possible to include variable definitions as in a X# shell script. If necessary, these can include defaults such as X# ${JH:-/u/j/h} but not termination constructs such as: ${XYZ:?} X# Note that spaces are not allowed in definitions. X# X# -- Comment lines start with a hash (#) X# -- Blank lines are ignored X# -- Tabs are non-preferred characters X################################################################## X X################################################################## X# Distributed file Compiled file # X################################################################## X X# Programs Xbin/cpinfxdir cpinfxdir Xbin/fl fl Xbin/ixcheck ixcheck Xbin/ixchkperm ixchkperm Xbin/ixclean ixclean Xbin/ixcomp ixcomp Xbin/ixconfig ixconfig Xbin/ixcreate ixcreate Xbin/ixcrontab ixcrontab Xbin/ixdaily ixdaily Xbin/ixhourly ixhourly Xbin/ixmail ixmail Xbin/ixmsgpath ixmsgpath Xbin/ixremove ixremove Xbin/ixrestart ixrestart Xbin/ixrstmsg ixrstmsg Xbin/ixsetperm ixsetperm Xbin/ixstats ixstats Xbin/ixwarn ixwarn Xbin/ixweekly ixweekly Xbin/ixzero ixzero Xbin/mkinfxdir mkinfxdir Xbin/mkixcpio mkixcpio Xbin/unixwarn unixwarn X Xetc/crontab crontab Xetc/ius.rc ius.rc Xetc/ixcheck-cD ixcheck-cD Xetc/ixcheck-cI ixcheck-cI Xetc/ixcheck-cc ixcheck-cc Xetc/ixcheck-ce ixcheck-ce Xetc/ixcheck-cr ixcheck-cr Xetc/ods.rc ods.rc X X# Documentation Xman/man1/cpinfxdir.1 cpinfxdir.1 Xman/man1/informix.1 informix.1 Xman/man1/ixcreate.1 ixcreate.1 Xman/man1/ixremove.1 ixremove.1 Xman/man1/mkinfxdir.1 mkinfxdir.1 Xman/man1/mkixcpio.1 mkixcpio.1 X X# Distribution tools Xetc/instfile instfile Xjlss jlss Xetc/mkpath mkpath Xetc/ixadm.lst ixadm.lst Xetc/ixadm.ins ixadm.ins SHAR-EOF chmod 444 ixadm.bod if [ `wc -c ixadm.ins <<'SHAR-EOF' X# "@(#)$Id: ixadm.ins,v 1.2 1997/05/12 09:46:37 johnl Exp $" X# X# JLSS Informix Administration Tools Version 2 (1997-05-12) X# X# Installation configuration file X Xenvdir=IXADMDIR Xdefdir=/usr/informix Xenvusr=IXADMUSR Xdefusr=bin Xenvgrp=IXADMGRP Xdefgrp=bin Xenvtmp=IXADMTMP Xdeftmp=${TMPDIR:-/tmp}/ixadm X XFILELIST=etc/ixadm.lst XPRODUCT="JLSS Informix Administration Tools Version 2 (1997-05-12)" X X################################################# X XIN_MSG=' Xecho " Base Directory: $envdir = $DIR" Xecho " Owner: $envusr = $USR" Xecho " Group: $envgrp = $GRP" Xecho "" Xecho "The executables will go in $envdir/bin" Xecho "The documentation will go in $envdir/man/man1" Xecho "The other files will go in $envdir/etc" X' X XIN_TRAP=" Xecho 'Set: $envdir to define the location of the programs' Xecho ' $envusr to define the owner' Xecho ' $envgrp to define the group' Xtrap 0 Xexit 1" X XRM_MSG=' Xecho " Base Directory: $envdir = $DIR" Xecho " Owner: $envusr = $USR" Xecho " Group: $envgrp = $GRP" Xecho "" Xecho "The executables were placed in $envdir/bin" Xecho "The documentation were placed in $envdir/man/man1" Xecho "The other files were placed in $envdir/etc" X' X XRM_TRAP=" Xecho 'Set: $envdir to define the location of the programs' Xecho ' $envusr to define the owner' Xecho ' $envgrp to define the group' Xecho ' $envtmp to define where the files are to be moved to' Xtrap 0 Xexit 1" SHAR-EOF chmod 444 ixadm.ins if [ `wc -c ixadm.lst <<'SHAR-EOF' X# @(#)$Id: ixadm.lst,v 1.4 1997/05/12 11:42:32 johnl Exp $ X# X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# @(#)Definitive list of files -- Installed Software X# X# -- The installed file column contains the name of the file to be X# installed. The name is quoted relative to the base directory. X# The name could also be prefixed with an environment variable X# which would be set by the installation script. X# X# -- The type of file indicates what sort of file is to be installed. X# -- The type "file" indicates an ordinary file. X# -- The type "directory" indicates that the file is the name of a X# directory which must exist when the software is installed. X# The installation program will create the directory X# if it does not already exist. The directory entry must come before X# the first file entry which lives in the directory. X# -- The type "deleted" means that this file used to exist in a previous X# release of the software and is no longer relevant. The file will X# be removed from the installed system. It can also be used to clean X# up after the installation process. X# -- The type "link" means that the installed file is a link to a file X# already installed. The name in the Link column is the name of the X# file which the file is to be linked to. X# This file must already exist. If the line is not a link entry, a X# dummy value (conventionally '-') must be present in the column. X# -- The type "exec" means that the installed file is executed. If the X# link field is not '-', then it is passed to the program as its sole X# argument. The configuration file (ixadm.ins) should have set any X# extra environment variables needed. Note that the installed file X# must be executable. X# X# -- Permissions are the file permissions to be set on the file. X# The three subfields are owner, group, mode. X# The owner - is used to indicate the owner of CODE. X# The group - is used to indicate the group of CODE. X# Other owner/group values are treated as literal values. X# X# -- Comment lines start with a hash (#) X# -- Blank lines are ignored X# -- Tabs are non-preferred characters X# X# Installed file Type Link Permissions X X. directory - - - 755 Xjlss file - - - 544 X X# Programs Xbin directory - - - 755 Xbin/cpinfxdir file - - - 755 Xbin/fl file - - - 755 Xbin/ixcheck file - - - 755 Xbin/ixchkperm file - - - 755 Xbin/ixclean file - - - 755 Xbin/ixcomp file - - - 755 Xbin/ixconfig file - - - 755 Xbin/ixcreate file - - - 755 Xbin/ixcrontab file - - - 755 Xbin/ixdaily file - - - 755 Xbin/ixhourly file - - - 755 Xbin/ixmail file - - - 755 Xbin/ixmsgpath file - - - 755 Xbin/ixremove file - - - 755 Xbin/ixrestart file - - - 755 Xbin/ixrstmsg file - - - 755 Xbin/ixsetperm file - - - 755 Xbin/ixstats file - - - 755 Xbin/ixwarn file - - - 755 Xbin/ixweekly file - - - 755 Xbin/ixzero file - - - 755 Xbin/mkinfxdir file - - - 755 Xbin/mkixcpio file - - - 755 Xbin/unixwarn file - - - 755 X X# Documentation Xman directory - - - 755 Xman/man1 directory - - - 755 Xman/man1/cpinfxdir.1 file - - - 644 Xman/man1/informix.1 file - - - 644 Xman/man1/ixcreate.1 file - - - 644 Xman/man1/ixremove.1 file - - - 644 Xman/man1/mkinfxdir.1 file - - - 644 Xman/man1/mkixcpio.1 file - - - 644 X X# Configuration files Xetc directory - - - 755 Xetc/crontab file - - - 644 Xetc/ius.rc file - - - 644 Xetc/ixcheck-cD file - - - 644 Xetc/ixcheck-cI file - - - 644 Xetc/ixcheck-cc file - - - 644 Xetc/ixcheck-ce file - - - 644 Xetc/ixcheck-cr file - - - 644 Xetc/ods.rc file - - - 644 X X# Distribution tools Xetc/ixadm.ins file - - - 444 Xetc/ixadm.lst file - - - 444 Xetc/jlss link jlss - - 544 Xjlss deleted - - - - SHAR-EOF chmod 444 ixadm.lst if [ `wc -c ixcheck-cD <<'SHAR-EOF' X# @(#)$Id: ixcheck-cD,v 1.2 1995/03/31 11:30:05 johnl Exp $ -- sed script for post-processing oncheck or tbcheck -cD output Xs/[ ][ ]*$// X/^$/d X/TBLSpace data check for/d SHAR-EOF chmod 444 ixcheck-cD if [ `wc -c ixcheck-cI <<'SHAR-EOF' X# @(#)$Id: ixcheck-cI,v 1.2 1995/03/31 11:30:06 johnl Exp $ -- sed script for post-processing oncheck or tbcheck -cI output Xs/[ ][ ]*$// X/^$/d X/Validating indexes for/d X/Index/d SHAR-EOF chmod 444 ixcheck-cI if [ `wc -c ixcheck-cc <<'SHAR-EOF' X# @(#)$Id: ixcheck-cc,v 1.2 1995/03/31 11:30:07 johnl Exp $ -- sed script for post-processing oncheck or tbcheck -cc output Xs/[ ][ ]*$// X/^$/d X/Validating database/d X/Validating sys[a-z]* for database/d X/WARNING:No sys[a-z]* records found/d SHAR-EOF chmod 444 ixcheck-cc if [ `wc -c ixcheck-ce <<'SHAR-EOF' X# @(#)$Id: ixcheck-ce,v 1.2 1995/03/31 11:30:09 johnl Exp $ -- sed script for post-processing oncheck or tbcheck -ce output Xs/[ ][ ]*$// X/^$/d X/Validating extents.../d SHAR-EOF chmod 444 ixcheck-ce if [ `wc -c ixcheck-cr <<'SHAR-EOF' X# @(#)$Id: ixcheck-cr,v 1.2 1995/03/31 11:30:10 johnl Exp $ -- sed script for post-processing oncheck or tbcheck -cr output Xs/[ ][ ]*$// X/^$/d X/Validating INFORMIX-OnLine reserved pages/d X/Validating PAGE_PZERO/d X/Validating PAGE_CONFIG/d X/Validating PAGE_1CKPT & PAGE_2CKPT/d X/Using check point page PAGE_[12]CKPT/d X/Validating physical log pages/d X/Validating logical logs/d X/Validating PAGE_1DBSP & PAGE_2DBSP/d X/Using dbspace page PAGE_[12]DBSP/d X/Validating PAGE_1PCHUNK & PAGE_2PCHUNK/d X/Using primary chunk page PAGE_[12]PCHUNK/d X/Validating PAGE_1MCHUNK & PAGE_2MCHUNK/d X/Using mirror chunk page PAGE_[12]MCHUNK/d X/Validating PAGE_1ARCH & PAGE_2ARCH/d X/Using archive page PAGE_[12]ARCH/d SHAR-EOF chmod 444 ixcheck-cr if [ `wc -c ixcheck.sh <<'SHAR-EOF' X: "@(#)$Id: ixcheck.sh,v 1.2 1995/03/31 11:30:12 johnl Exp $" X# X# Run tbcheck on OnLine system (and its databases), reporting oddities X Xarg0=`basename $0 .sh` X Xif [ $# -eq 0 ] Xthen X X # Do the full set of checks X $0 -cr # Reserved pages X $0 -ce # Extents X dbnames | X while read dbnum dbase X do X $0 -cc $dbase # Catalogue X $0 -cD $dbase # Data pages X $0 -cI $dbase # Index pages X done X Xelse X X ixd=${INFORMIXDIR:-/usr/informix} X ixb=$ixd/bin X tbcheck=$ixb/oncheck X if [ ! -f $tbcheck ] X then tbcheck=$ixb/tbcheck X fi X if [ ! -f $tbcheck ] X then X echo "$arg0: cannot locate oncheck or tbcheck" >&2 X exit 1 X fi X X # Do one specific check X tmp=${TMPDIR:-/tmp}/ixck.$$ X trap "rm -f $tmp.* ; exit 1" 1 2 3 13 15 X admfile=$arg0$1 X if [ ! -f $admfile ] X then X if [ -f $ixd/etc/$admfile ] X then admfile=$ixd/etc/$admfile X elif [ -f $ixd/adm/$admfile ] X then admfile=$ixd/adm/$admfile X else echo "$arg0: cannot locate filter file $admfile" >&2 X exit 1 X fi X fi X X # tbcheck -cc succeeds with status 0 X # tbcheck -cI succeeds with status 0 X # tbcheck -cD succeeds with status 1 -- damn bugs! X tbconfig=${ONCONFIG:-${TBCONFIG:-tbconfig}} X $tbcheck $* >$tmp.1 X if [ $? -gt 128 ] X then X ixmail -s "$tbconfig: `basename $tbcheck` $* core dumped" <$tmp.1 X elif [ $? -ne 0 -a $? -ne 1 ] X then X ixmail -s "$tbconfig: `basename $tbcheck` $* failed" <$tmp.1 X elif sed -f $admfile $tmp.1 >$tmp.2 && [ -s $tmp.2 ] X then X ixmail -s "$tbconfig: `basename $tbcheck` $* errors" <$tmp.1 X fi X rm -f $tmp.* X Xfi SHAR-EOF chmod 444 ixcheck.sh if [ `wc -c ixchkperm.sh <<'SHAR-EOF' X: "@(#)$Id: ixchkperm.sh,v 1.3 1996/08/27 16:56:43 johnl Exp $" X# X# Check permissions on Informix software X Xtmp=${TMPDIR:-/tmp}/ixsp.$$ Xstatus=1 Xtrap 'rm -f $tmp.?; exit $status' 0 1 2 3 13 15 X Xcd ${INFORMIXDIR:=/usr/informix} X Xsed -e 's/#.*//' \ X -e '/^[ ]*$/d' \ X -e '/^PRODUCT[ ]/d' \ X -e '/^NAME[ ]/d' \ X -e 's/[ ][ ]*$//' \ X -e 's/[ ][ ]*/ /g' \ X ${*:-etc/*files} | Xcut -d' ' -f1-4 | Xsort -u +0 -1 | Xtee $tmp.1 | Xsed 's/[ ].*//' | Xxargs fl -LD -nogQ 2>/dev/null > $tmp.2 X Xjoin $tmp.1 $tmp.2 | Xwhile read file std_owner std_group std_perms act_owner act_group act_perms Xdo X if [ $act_owner != $std_owner ] X then echo "$file: actual owner $act_owner != official owner $std_owner" X fi X if [ $act_group != $std_group ] X then echo "$file: actual group $act_group != official group $std_group" X fi X if [ $act_perms -ne $std_perms ] X then echo "$file: actual perms $act_perms != official perms $std_perms" X fi Xdone X Xstatus=0 SHAR-EOF chmod 444 ixchkperm.sh if [ `wc -c ixclean.sh <<'SHAR-EOF' X: "@(#)$Id: ixclean.sh,v 1.2 1997/05/12 11:30:06 johnl Exp $" X# X# Informix Log Directory Cleanup Script X X: ${INFORMIXDIR:=/usr/informix} X X# Remove old files (more than 30 days) Xfind $INFORMIXDIR/log -type f -mtime +30 -print | Xxargs rm -f X X# Compress uncompressed files in subdirectories Xixcomp X X# Remove empty directories (except $INFORMIXDIR/log) Xfind $INFORMIXDIR/log/* -type d -depth -print | Xxargs rmdir 2>/dev/null SHAR-EOF chmod 444 ixclean.sh if [ `wc -c ixcomp.sh <<'SHAR-EOF' X: "@(#)$Id: ixcomp.sh,v 1.2 1997/05/12 11:25:33 johnl Exp $" X# X# Informix Log Directory Compression Script X X: ${INFORMIXDIR:=/usr/informix} X: ${IXADM_COMPRESS:=gzip} X X# Compress any uncompressed files in any directory under $INFORMIXDIR/log. Xfind $INFORMIXDIR/log/* -type f -print | Xegrep -v '\.(Z|z|gz)$' | Xgrep -v "$INFORMIXDIR/log/[^/]*$" | Xxargs ${IXADM_COMPRESS} SHAR-EOF chmod 444 ixcomp.sh if [ `wc -c ixconfig.sh <<'SHAR-EOF' X: "@(#)$Id: ixconfig.sh,v 1.2 1995/03/31 11:31:04 johnl Exp $" X# X# Return value of ONCONFIG or TBCONFIG parameter X# X# Usage: ixconfig parameter [configfile] X# Default config file: tbconfig X Xarg0=`basename $0 .sh` X Xcase $# in X1|2) : OK;; X*) echo "Usage: $arg0 parameter [configfile]" >&2 X exit 1;; Xesac X Xparameter=$1 Xtbconfig=${2:-${ONCONFIG:-${TBCONFIG:-tbconfig}}} Xif [ -f $tbconfig ] Xthen configfile=$tbconfig Xelse configfile=${INFORMIXDIR:-/usr/informix}/etc/$tbconfig Xfi X Xerror(){ Xecho "$arg0: $*" >&2 Xexit 1 X} X X[ -f $configfile ] || error "cannot locate config file $configfile" X[ -r $configfile ] || error "cannot read config file $configfile" X Xblanktab=" " Xtab=" " X X# Analysis of SED script X# 1. Strip leading blanks/tabs X# 2. Strip comments X# 3. Strip blank lines X# 4. Delete lines not matching parameter X# 5. Replace blanks/tabs by tab Xsed -e "s/^[$blanktab]*//" \ X -e "s/[$blanktab]*#.*//" \ X -e "/^[$blanktab]*$/d" \ X -e "/$parameter[$blanktab]/!d" \ X -e "s/[$blanktab][$blanktab]*/$tab/g" \ X $configfile | Xcut -f2 SHAR-EOF chmod 444 ixconfig.sh if [ `wc -c ixcreate.1 <<'SHAR-EOF' Xixcreate is designed to install Informix files into a local directory using Xthe files already installed in some remote directory. X XIt has the following options: X X -F file The name of the file list X -R remote The directory where the software is already installed X -L local The driectory where the software is needed X -c Copy: copy files from remote directory X -d Demo: include demo files (excluded by default) X -f Force: replace any existing file in the local directory X -g Do not set group for files X -l Link: link files from remote directory (default; sym link) X -n Do not execute anything X -o Do not set owner for files X -p Do not set permissions for files X -s Silent operation X -v Verbose: say what you are doing X XTypical use: X Xixcreate -R /software/informix/6.00.UE1 -L /work/bonsai/sqldist \ X -F onlinefiles -F sefiles -F esqlfiles -lf X XIn the context of installing Tools into a working Engines directory, the use Xwould be: X Xixcreate -R /tmp/tools -L /usr/informix/6.00.UE1 \ X -F fglfiles -F fgpfiles -F sqlfiles -F fgldbfiles -c X XIf no file list options are specified, it installs all the products Xavailable in the remote directory, using the $REMOTE/etc/*files pattern to Xdetermine the available products. X XIt is an error if both '-l' and '-c' are specified. X XNotes on permission setting: X* Directories are always created, not linked. X* If a file is copied, its permissions are set, whereas if it is linked, X they are not. X* When permissions are set, the three components (owner, group, perms) can X be disabled independently using the -o, -g -p options respectively. X* The target directory (-L) need not exist; it is created using 'mkdir -p' X if necessary. You can override this by setting $MKDIR in the environment. X SHAR-EOF chmod 444 ixcreate.1 if [ `wc -c ixcreate.sh <<'SHAR-EOF' X: "@(#)$Id: ixcreate.sh,v 1.16 1997/05/02 15:55:36 johnl Exp $" X# X# Install selected Informix software. X# X# * Should normally be run by root as it uses chown/chgrp to set permissions. X# * Although intended for use on R&D machines, it will work on others, but X# typically it will need to be invoked with -L and -R options to specify X# the correct local and remote directories. X# * The software is assumed to be installed in the remote directory with X# the correct permissions if symbolic links (the default) are used. X# * If invoked with no filelist arguments, it installs all the products X# installed in the remote directory. X# * If invoked using symbolic links and the remote directory is specified X# with a relative path name (instead of an absolute path name), then the X# links are created correctly even in sub-directories (which takes more X# fiddling than you'd believe). Note that the relative mode works with X# the remote directory in any location relative to the current directory, X# so that both "ixcreate -R ../some/where" AND "ixcreate -R some/where" X# will be OK. X Xarg0=`basename $0 .sh` Xusage="Usage: $arg0 [-L localdir] [-R remotedir] [-F filelist] [-c|-l] [-dfgnopsv]" X XPATH=$PATH:/etc # Pick up /etc/chown on SunOS 4.1.3 Xexport PATH X X: ${MKDIR:="mkdir -p"} XREMOTE=${REMOTE:-${INFORMIXENG:-${INFORMIXDIR:-/usr/informix}}} XLOCAL=${LOCAL:-${SQLDIST:-`pwd`}} XLINK="" Xmode="" Xforce=no Xfilelist="" Xsilent=no Xremovedemo="-e /demo/d" Xverbose=no Xexecute=yes Xchown=chown Xchgrp=chgrp Xchmod=chmod X Xerror(){ X echo "$*" >&2 X exit 1 X} X Xusage(){ X error "$usage" X} X Xset -- `getopt cdfglnopsvF:L:R: ${@:+"$@"}` X Xwhile [ $# -gt 0 ] Xdo X case "$1" in X --) shift; break;; X -c) [ -n "$mode" ] && usage; mode="Copy";; X -d) removedemo=;; X -f) force=yes;; X -g) chgrp=":";; X -l) [ -n "$mode" ] && usage; mode="SymLink";; X -n) execute=no;; X -o) chown=":";; X -p) chmod=":";; X -s) silent=yes; verbose=no;; X -v) verbose=yes; silent=no;; X -L) LOCAL=$2; shift;; X -R) REMOTE=$2; shift;; X -F) filelist="$filelist $2"; shift;; X *) usage;; X esac X shift Xdone X Xif [ $# -gt 0 ] Xthen usage Xfi X X# On Solaris, in both Bourne and Korn shell, the -d operator will follow X# any symlinks and check the real file at the far end. This also applies X# to almost all the other test operators that check the file type, except X# for the test operators -h or -L which explicitly test for symlinks. Xif [ -d $LOCAL ] Xthen : OK Xelif $MKDIR $LOCAL Xthen : OK Xelse error "$arg0: unable to create local 'directory' $LOCAL" Xfi X Xif [ ! -d $REMOTE ] Xthen error "$arg0: remote 'directory' $REMOTE isn't a directory" Xfi X Xif [ -z "$mode" ] Xthen mode="SymLink" Xfi X Xif [ -z "$filelist" ] Xthen filelist=`cd $REMOTE/etc; ls *files` Xfi X Xif [ "$mode" = "SymLink" ] Xthen LINK="ln -s" X case "$REMOTE" in X /*) : OK;; X *) #case "$LOCAL" in X #.) mode="RelLink";; X #*) error "In relative link mode, the local directory must be '.'";; X #esac;; X mode="RelLink";; X esac Xelif [ "$mode" = "Copy" ] Xthen LINK="cp" Xelse error "Internal error -- unknown mode '$mode'" Xfi X Xfiles="" Xfor file in $filelist Xdo X case $file in X /*) nfile=$file;; X *) nfile=$REMOTE/etc/$file;; X esac X if [ -r $nfile ] X then files="$files $nfile" X else error "$arg0: cannot locate $nfile" X fi Xdone X Xif [ $silent = no ] Xthen X echo "Using '$LINK' to install files" X echo "Old INFORMIXDIR is: $REMOTE" X echo "New INFORMIXDIR is: $LOCAL" X sed -n '/^PRODUCT/s/PRODUCT[ ]*//p' $files Xfi X Xlogcommand(){ X if [ $verbose = yes ] X then echo " $1 $2" X fi X if [ $execute = yes ] X then shift 2; $* X fi X} X X# setperms owner group perms file... X# NB: C-ISAM lists owner and group as '-'. Xsetperms(){ X owner=$1 X group=$2 X perms=$3 X shift 3 X $chmod $perms $* && X [ "x$group" != "x-" ] && $chgrp $group $* && X [ "x$owner" != "x-" ] && $chown $owner $* X} X X# Set TEST_SYMLINK_OPTION in the environment if '-h' is not the correct option XH=${TEST_SYMLINK_OPTION:-'-h'} X Xsed -e 's/#.*//' -e '/^[ ]*$/d' -e '/^PRODUCT/d' -e '/^NAME/d' \ X -e 's/[ ][ ]*/ /g' $removedemo $files | Xsort -u | X X{ Xlinks="" Xwhile read file owner group perms link linkfile junk Xdo X case $file in X /*) # Absolute file names -- typically in /usr/lib. Ugh! X local=$file X remote=$file;; X *) # Relative file names -- normal and non-controversial. X local=$LOCAL/$file X remote=$REMOTE/$file;; X esac X if [ -d $remote ] X then X # Install a directory X if [ ! -d $local ] X then X rm -f $local X logcommand Mkdir $file ${MKDIR} $local && X if [ $execute = yes ] X then setperms $owner $group $perms $local X fi X fi X else X # Install a file X if [ $force = yes ] X then rm -f $local X fi X X setperm=no X if [ ! -f $local ] X then X # Remove local file if it's a symlink pointing nowhere X if [ $H $local ] X then rm -f $local X fi X # $link can be plain "-" X if [ "x$link" = xLINK ] X then X logcommand Link "$linkfile to $file" : OK X case $linkfile in X /*) links="${links}ln $linkfile $local;";; X *) links="${links}ln $LOCAL/$linkfile $local;";; X esac X elif [ "x$link" = xREMOVE ] X then logcommand Remove $file rm -f $local X elif [ "x$link" = xELINK ] X then X : Ignore ELINK X # ELINK links an existing file $linkfile to the new name X # specified as $file. Used in onlinefiles to rename X # tbconfig to onconfig. X else X # "x$link" in {"", "-", "BRAND", "REPLACE", "RENAME"} X # REPLACE will back up current version of $file and then X # install new one. RENAME will copy $file in and then X # rename it to $linkfile. In all cases, copy file to X # distribution. X if [ "$mode" = "RelLink" ] X then X # Convert the path portion of the local file name into X # a sequence of "../" units. Sed script: X # 1. strips leading "./"; X # 2. prints current directory "." and quit; X # 3. converts plain directory name to '..'; X # 4. converts leading "xyz/" to "../"; X # 5. converts trailing "/xyz" to "/..". X relpath=`dirname $local | X sed -e 's%^\./%%' \ X -e '/^\.$/q' \ X -e 's%^[^/][^/]*$%..%' \ X -e 's%[^/]*/%../%g' \ X -e 's%/[^/]*$%/..%'` X remote=$relpath/$remote X fi X logcommand $mode $file $LINK $remote $local && X setperm=yes X fi X fi X X if [ "$LINK" = cp -a $setperm = yes ] X then setperms $owner $group $perms $local X fi X fi Xdone X Xif [ -n "$links" ] Xthen X if [ $execute = yes ] X then eval $links X fi Xfi X} SHAR-EOF chmod 444 ixcreate.sh if [ `wc -c ixcrontab.sh <<'SHAR-EOF' X: "@(#)$Id: ixcrontab.sh,v 1.1 1993/06/13 00:32:08 jl Exp $" X# X# Run crontab, but only if real UID is "informix" X Xusr=`id | sed 's/uid=[0-9][0-9]*(\([^)]*\)).*/\1/'` Xif [ "$usr" != "informix" ] Xthen echo "Not informix: crontab unchanged" >&2 && exit 1 Xelse crontab ${@:+"$@"} Xfi SHAR-EOF chmod 444 ixcrontab.sh if [ `wc -c ixdaily.sh <<'SHAR-EOF' X: "@(#)$Id: ixdaily.sh,v 1.2 1993/06/13 01:12:49 jl Exp $" X# X# Informix DAILY Cron Job X X# Run by cron => minimal environment X: ${INFORMIXDIR:=/usr/informix} Xexport INFORMIXDIR X XPATH=$PATH:$INFORMIXDIR/bin Xexport PATH X X# Compress logs Xixcomp X X# Check system integrity Xixcheck SHAR-EOF chmod 444 ixdaily.sh if [ `wc -c ixhourly.sh <<'SHAR-EOF' X: "@(#)$Id: ixhourly.sh,v 1.4 1995/03/31 11:30:04 johnl Exp $" X# X# Informix HOURLY Cron Job X X# Run by cron => minimal environment X: ${INFORMIXDIR:=/usr/informix} Xexport INFORMIXDIR X XPATH=$PATH:$INFORMIXDIR/bin Xexport PATH X X# Collect statistics Xixstats X X# Warn about Informix resource problems Xixwarn X X# Warn about Unix resource problems Xunixwarn X X# Warn about online problems Xixmsgpath X X# Zero stats Xixzero SHAR-EOF chmod 444 ixhourly.sh if [ `wc -c ixmail.sh <<'SHAR-EOF' X: "@(#)$Id: ixmail.sh,v 1.1 1993/06/13 00:25:05 jl Exp $" X# X# Conditionally send mail to user informix X Xtmp=${TMPDIR:-/tmp}/ixm.$$ Xtrap "rm -f $tmp; exit 1" 1 2 3 13 15 X X# Filter out trailing blanks and tabs X# Remove multiple, identical lines Xsed -e 's/[ ][ ]*$//' | Xuniq >$tmp X X# Is there anything left? Xnc=`wc -c <$tmp` Xif [ $nc -gt 1 ] Xthen X # Yes -- send it X users= X title= X flags= X while [ $# -gt 0 ] X do X case "$1" in X -s) title="$2"; shift;; X -?) flags="$flags $1";; X *) users="$users $1";; X esac X shift X done X : ${MAILER:=mailx} X : ${users:=informix} X : ${title='Informix Mail'} X MAILRC=/dev/null ${MAILER} $flags -s "$title" ${users} <$tmp Xfi X X# Clean up Xrm -f $tmp Xexit 0 SHAR-EOF chmod 444 ixmail.sh if [ `wc -c ixmsgpath.sh <<'SHAR-EOF' X: "@(#)$Id: ixmsgpath.sh,v 1.2 1993/06/13 11:48:04 jl Exp $" X# X# Report on new, significant messages in MSGPATH file X Xarg0=`basename $0 .sh` X Xerror(){ Xecho "$arg0: $*" >&2 Xexit 1 X} X Xixd=${INFORMIXDIR:-/usr/informix} Xmsg=`ixconfig MSGPATH` X X[ -n "$msg" ] || error "cannot determine value for MSGPATH" X[ -f "$msg" ] || error "cannot locate MSGPATH file $msg" X[ -r "$msg" ] || error "cannot read MSGPATH file $msg" X Xlogdir=$ixd/log X[ -d $logdir ] || error "cannot locate log directory $logdir" X Xmsgpath=$logdir/msgpath Xowc=`grep "^$msg " $msgpath 2>/dev/null | cut -f2` Xif [ -z "$owc" ] Xthen X owc=1 X echo "$msg $owc" >>$msgpath Xfi Xnwc=`wc -l <$msg` Xnwc=`echo $nwc` X Xtmp=${TMPDIR:-/tmp}/msg.$$ Xtrap "rm -f $tmp.*; exit 1" 1 2 3 13 15 X X# Collect new information Xsed -n "${owc},${nwc}p" $msg >$tmp.1 X X# Update log record Xed - $msgpath <ixremove.1 <<'SHAR-EOF' XThe ixremove command removes the files unique to a named product or Xspecified file list. You could remove the Tools specific files from an XINFORMIXDIR by doing: X Xcd $INFORMIXDIR Xixremove -F fglfiles -F fgpfiles -F fgldbfiles -F sqlfiles -v X XThis would remove all the Tools files not used by the Engines from X$INFORMIXDIR. X XOptions: X -n Do not execute the commands X -v Verbose: echo what the command is doing (or would do) X -q Do not report on non-existent files X -F file Remove product by file-list name X -I dir Remove files from this directory (instead of $INFORMIXDIR) X XNB: The -v and -q options are not mutually exclusive. X X@(#)$Id: ixremove.1,v 1.3 1996/01/26 22:06:24 johnl Exp $ SHAR-EOF chmod 444 ixremove.1 if [ `wc -c ixremove.sh <<'SHAR-EOF' X: "@(#)$Id: ixremove.sh,v 1.7 1997/05/02 15:56:18 johnl Exp $" X# X# Remove an Informix product from $INFORMIXDIR. X# Does not remove any files used by products still installed. X Xarg0=`basename $0 .sh` Xusage="Usage: $arg0 [-F filelist] [-I informixdir] [-nvq]" X X# Verbose means report on the files removed X# Quiet means do not report on missing files X# The Verbose and Quiet options are not mutually exclusive Xfilelist="" Xverbose=no Xexecute=yes Xprodlist="" Xquiet=no X Xset -- `getopt -fnqvF:I: ${@:+"$@"}` X Xwhile [ $# -gt 0 ] Xdo X case "$1" in X --) shift X break;; X -q) quiet=yes;; X -v) verbose=yes;; X -n) execute=no;; X -I) INFORMIXDIR="$2" X shift;; X -F) filelist="$filelist $2" X shift;; X *) echo "$usage" >&2 X exit 1;; X esac X shift Xdone X Xif [ $# -gt 0 ] Xthen X echo "$usage" >&2 X exit 1 Xfi X Xif [ ! -d ${INFORMIXDIR:=/usr/informix} ] Xthen X echo "$arg0: The INFORMIXDIR 'directory' $INFORMIXDIR isn't a directory" >&2 X exit 1 Xfi X Xxflag=-u Xif [ $verbose = yes ] Xthen xflag=${xflag}v Xfi Xif [ $execute = no ] Xthen xflag=${xflag}n Xfi X Xif [ -z "$filelist" ] Xthen X echo "$usage" >&2 X exit 1 Xfi X Xfiles="" Xnames="" Xfor file in $filelist Xdo X case "$file" in X /*) nfile=$file;; X *) nfile=$INFORMIXDIR/etc/`basename $file`;; X esac X if [ ! -r $nfile ] X then echo "$arg0: cannot locate $nfile" >&2; exit 1 X else X files="$files $nfile" X names="$names -e `basename $nfile`" X fi Xdone Xecho "$arg0: removing files listed solely in $filelist from $INFORMIXDIR" X Xtmp=${TMPDIR:-/tmp}/unix.$$ Xtrap "rm -f $tmp.?; exit 1" 1 2 3 13 15 X Xls $INFORMIXDIR/etc/*files >$tmp.1 2>/dev/null Xfgrep $names $tmp.1 > $tmp.2 2>/dev/null Xif [ -s $tmp.2 ] Xthen X echo "These file lists will be ignored:" X sed 's/^/ /' $tmp.2 Xfi Xfgrep -v $names $tmp.1 > $tmp.2 2>/dev/null X Xls $files > $tmp.1 X# Add /dev/null to allow the remainder to be empty. Xremainder="`comm -13 $tmp.1 $tmp.2` /dev/null" X Xstreamline(){ Xsed -e 's/#.*//' \ X -e '/^[ ]*$/d' \ X -e '/^PRODUCT/d' \ X -e '/^NAME/d' \ X -e 's/[ ][ ]*/ /g' $* X} X Xstreamline $files | sort -u >$tmp.1 Xstreamline $remainder | sort -u >$tmp.2 X X# Set TEST_SYMLINK_OPTION in the environment if '-h' is not the correct option XH=${TEST_SYMLINK_OPTION:-'-h'} X Xcomm -23 $tmp.1 $tmp.2 | X{ Xdirlist="" Xwhile read file owner group perms link linkfile junk Xdo X # Allow for absolute path names (probably shared libraries) X case $file in X /*) echo "echo Not removing absolute file name $file"; continue;; X *) ixfile=$INFORMIXDIR/$file;; X esac X if [ "$link" = REMOVE ] X then : Ignore REMOVE files -- should not exist anyway! X elif [ $H $ixfile ] X then echo "rm -f $ixfile" X elif [ -f $ixfile ] X then echo "rm -f $ixfile" X elif [ -d $ixfile ] X then dirlist="$ixfile $dirlist" X elif [ $quiet = no ] X then echo "$arg0: warning $ixfile not found" >&2 X fi Xdone X# Remove directories (ignoring errors) Xif [ -n "$dirlist" ] Xthen echo "rmdir $dirlist >/dev/null 2>&1" Xfi X} | Xsh ${xflag} X Xrm -f $tmp.? SHAR-EOF chmod 444 ixremove.sh if [ `wc -c ixrestart.sh <<'SHAR-EOF' X: "@(#)$Id: ixrestart.sh,v 1.4 1995/03/31 11:30:03 johnl Exp $" X# X# Shutdown Informix-OnLine and then restart it. X Xarg0=`basename $0 .sh` X Xixb=${INFORMIXDIR:-/usr/informix}/bin Xtbstat=$ixb/onstat Xtbmode=$ixb/onmode Xtbinit=$ixb/oninit X Xif [ ! -f $tbstat ] Xthen X tbstat=$ixb/tbstat X tbmode=$ixb/tbmode X tbinit=$ixb/tbinit Xfi X Xif [ ! -f $tbstat ] Xthen X echo "$arg0: cannot locate onstat or tbstat" >&2 X exit 1 Xfi X X# If OnLine is running, shut it down Xif $tbstat >/dev/null 2>&1 Xthen X # OnLine is running X $tbmode -ky X if $tbstat >/dev/null 2>&1 X then X echo "$arg0: cannot shut down Online" >&2 X exit 1 X fi Xfi X X# Reset MSGPATH logfile Xixrstmsg X X# Log is changed; restart OnLine X$tbinit SHAR-EOF chmod 444 ixrestart.sh if [ `wc -c ixrstmsg.sh <<'SHAR-EOF' X: "@(#)$Id: ixrstmsg.sh,v 1.1 1993/06/13 11:47:08 jl Exp $" X# X# Restart the MSGPATH log file X Xarg0=`basename $0 .sh` X Xerror(){ X echo "$arg0: $*" >&2 X exit 1 X} X X: ${INFORMIXDIR:=/usr/informix} XMSGPATH=`ixconfig MSGPATH` X X[ -n "$MSGPATH" ] || error "cannot determine MSGPATH" X[ -f "$MSGPATH" ] || error "cannot locate MSGPATH file $MSGPATH" X[ -r "$MSGPATH" ] || error "cannot read MSGPATH file $MSGPATH" X X# If running with more than one OnLine system on the machine, it is X# suggested that you use subdirectories under $INFORMIXDIR/log based X# on SERVERNAME or SERVERNUM, thus: X# LD=$INFORMIXDIR/log/`ixconfig SERVERNAME' X# LD=$INFORMIXDIR/log/server.`ixconfig SERVERNUM' X# You might want to error check the result of ixconfig. X X# Rename MSGPATH file Xdt=`date +"%Y.%m.%d"` Xtm=`date +"%H:%M:%S"` XLD=$INFORMIXDIR/log X[ -d $LD ] || mkdir $LD || error "cannot create $LD directory" X[ -d $LD/$dt ] || mkdir $LD/$dt || error "cannot create $LD/$dt directory" Xmv $MSGPATH $LD/$dt/log.$tm X X# Create a new, empty MSGPATH file Xcat /dev/null >$MSGPATH Xchmod 664 $MSGPATH Xchgrp informix $MSGPATH Xchown informix $MSGPATH X X# Update the MSGPATH log-file for ixmsgpath X# This will ensure that errors are reported X X# Ensure there is a MSGPATH log-file Xmsgpath=$LD/msgpath Xif [ ! -f $msgpath ] Xthen X cat /dev/null >$msgpath X chmod 664 $msgpath X chgrp informix $msgpath X chown informix $msgpath Xfi X X# Ensure there is an entry for this configuration Xif grep "^$MSGPATH " $msgpath >/dev/null 2>&1 Xthen : OK Xelse echo "$MSGPATH 1" >>$msgpath Xfi X X# Update the entry for this configuration Xed - $msgpath <ixsetperm.sh <<'SHAR-EOF' X: "@(#)$Id: ixsetperm.sh,v 1.3 1996/08/27 16:45:19 johnl Exp $" X# X# Generate script to set permissions on Informix software X Xtmp=${TMPDIR:-/tmp}/ixsp.$$ Xstatus=1 Xtrap 'rm -f $tmp.?; exit $status' 0 1 2 3 13 15 X Xcd ${INFORMIXDIR:=/usr/informix} X Xsed -e 's/#.*//' \ X -e '/^[ ]*$/d' \ X -e '/^PRODUCT[ ]/d' \ X -e '/^NAME[ ]/d' \ X -e 's/[ ][ ]*$//' \ X -e 's/[ ][ ]*/ /g' \ X ${*:-etc/*files} | Xcut -d' ' -f1-4 | Xsort -u +0 -1 | Xtee $tmp.1 | Xsed 's/[ ].*//' | Xxargs fl -LD -nogQ 2>/dev/null > $tmp.2 X Xjoin $tmp.1 $tmp.2 | Xwhile read file std_owner std_group std_perms act_owner act_group act_perms Xdo X if [ $act_owner != $std_owner ] X then echo chown $std_owner $file X fi X if [ $act_group != $std_group ] X then echo chgrp $std_group $file X fi X if [ $act_perms -ne $std_perms ] X then echo chmod $std_perms $file X fi Xdone | Xsort | Xnawk '# Xfunction print_cmd(cmd, arg, list, array, n, i) { X if (length(list) < 128) X print cmd " " arg " " list; X else X { X n = split(list, array) X print "xargs " cmd " " arg " <ixstats.sh <<'SHAR-EOF' X: "@(#)$Id: ixstats.sh,v 1.2 1995/03/31 11:30:01 johnl Exp $" X# X# Run TBSTAT and PS and record results in a log file X Xixb=${INFORMIXDIR:-/usr/informix}/bin Xtbstat=$ixb/onstat Xif [ ! -f $tbstat ] Xthen tbstat=$ixb/tbstat Xfi Xif [ ! -f $tbstat ] Xthen X echo "`basename $0 .sh`: cannot locate onstat or tbstat" >&2 X exit 1 Xfi X Xdt=`date +"%Y.%m.%d"` Xtm=`date +"%H:%M:%S"` XLD=$INFORMIXDIR/log Xif [ ! -d $LD/$dt ] Xthen X mkdir $LD/$dt Xfi X X{ Xecho TBSTAT: X$tbstat -plu Xecho Xecho PS: Xps -ef X} >$LD/$dt/ts.$tm SHAR-EOF chmod 444 ixstats.sh if [ `wc -c ixwarn.sh <<'SHAR-EOF' X: "@(#)$Id: ixwarn.sh,v 1.2 1995/03/31 11:30:02 johnl Exp $" X# X# Warn about critical Informix resource problems X Xixb=${INFORMIXDIR:-/usr/informix}/bin Xtbstat=$ixb/onstat Xif [ ! -f $tbstat ] Xthen tbstat=$ixb/tbstat Xfi Xif [ ! -f $tbstat ] Xthen X echo "`basename $0 .sh`: cannot locate onstat or tbstat" >&2 X exit 1 Xfi X X$tbstat -Fp | Xawk '# X/Fg Writes/ { fg = 1; next; } X/dskreads/ { pc = 1; next; } X/ovtbls/ { ov = 1; next; } X { X if (fg == 1) { X # Non-zero foreground writes are a problem! X if ($1 != 0) X print "Foreground Writes = ", $1; X } X if (pc == 1) { X # Read cache less than 90% is a problem X if ($4 < 90) X print "Read cache effciency = ", $4; X # Write cache less than 70% is a problem if the number X # of writes is a significant proportion of the reads. X # Significant is deemed to be 5% (1/20). X if ($8 < 70 && $3 < 20 * $7) X print "Write cache efficiency = ", $8; X } X if (ov == 1) { X if ($1 > 0) X print "Over tables = ", $1; X if ($2 > 0) X print "Over locks = ", $2; X if ($3 > 0) X print "Over users = ", $3; X if ($4 > 0) X print "Over buffers = ", $4; X } X pc = ov = fg = 0; X } X#' | Xixmail -s "Informix Resource Problems" Xexit 0 X X### Sample duff data (mangled to be duff) X Xcat <ixweekly.sh <<'SHAR-EOF' X: "@(#)$Id: ixweekly.sh,v 1.2 1993/06/13 01:12:51 jl Exp $" X# X# Informix WEEKLY Cron Job X X# Run by cron => minimal environment X: ${INFORMIXDIR:=/usr/informix} Xexport INFORMIXDIR X XPATH=$PATH:$INFORMIXDIR/bin Xexport PATH X X# Shut down and restart the OnLine system Xixrestart X X# Clean up the log directory Xixclean SHAR-EOF chmod 444 ixweekly.sh if [ `wc -c ixzero.sh <<'SHAR-EOF' X: "@(#)$Id: ixzero.sh,v 1.1 1995/03/31 11:29:43 johnl Exp $" X# X# Reset statistics to zero X Xixb=${INFORMIXDIR:-/usr/informix}/bin Xtbstat=$ixb/onstat Xif [ ! -f $tbstat ] Xthen tbstat=$ixb/tbstat Xfi Xif [ ! -f $tbstat ] Xthen X echo "`basename $0 .sh`: cannot locate onstat or tbstat" >&2 X exit 1 Xfi X X$tbstat -z SHAR-EOF chmod 444 ixzero.sh if [ `wc -c jlss.h <<'SHAR-EOF' X/* X@(#)File: $RCSfile: jlss.h,v $ X@(#)Version: $Revision: 1.3 $ X@(#)Last changed: $Date: 1997/05/01 10:43:18 $ X@(#)Purpose: JLSS Library Functions X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1997 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X X#ifndef JLSS_H X#define JLSS_H X X#ifdef MAIN_PROGRAM X#ifndef lint Xstatic const char jlss_h[] = "$Id: jlss.h,v 1.3 1997/05/01 10:43:18 johnl Exp $"; X#endif /* lint */ X#endif /* MAIN_PROGRAM */ X X#include X Xextern FILE *efopen(const char *name, const char *mode); Xextern char *vstrcpy(char *s1, int n, ...); Xextern const char *cistrstr(const char *s1, const char *s2); Xextern int cistrcmp(const char *s1, const char *s2); Xextern void fcopy(FILE *f1, FILE *f2); Xextern void image_print(FILE *fp, long offset, char *buffer, long nbytes); X X#endif /* JLSS_H */ SHAR-EOF chmod 444 jlss.h if [ `wc -c jlss.sh <<'SHAR-EOF' X: "$Id: jlss.sh,v 2.10 1997/05/12 11:15:27 johnl Exp $" X# X# @(#)Generic JLSS Installation and Uninstallation Tool X# @(#)(C) Copyright JLSS 1992-93,97 X X################################################################ X# This script may be run by Bourne Shell or Korn Shell # X################################################################ X# This is a big script to enable all the products installed # X# using this system to be handled on both installation and # X# uninstallation with only two auxilliary files -- the `.lst' # X# file and the `.ins' file. And too make life about as easy # X# as possible for the users, they only have to type 3 words # X# once they have set the environment correctly: # X# Either: jlss install prodcode # X# Or: jlss uninstall prodcode # X# where "prodcode" is the code name used by JLSS to identify # X# the set of software which is to be installed or uninstalled. # X# The corresponding configuration files are prodcode.lst and # X# prodcode.ins, and these are either in the current directory # X# "." or in "./etc". The software can be installed in either # X# the current directory or some other directory, and the other # X# directory need not exist prior to installing the software. # X################################################################ X# This script insists that root runs it to ensure that all the # X# mkdir, chmod, chgrp and chown commands succeed. If the user # X# will have sufficient privileges without being root, then the # X# test in the "Check Authorisation" section can be removed and # X# installation will proceed without problems. # X################################################################ X# The script is fussy about the environment variables set in # X# the configuration file so that any "exec" scripts can tell # X# where the software has been placed. # X################################################################ X# Set JLSS_NIS_INSTALL if the system uses NIS (or the user & # X# group names are not available in /etc/passwd and /etc/group # X# for any reason. The install may fail less gracefully if # X# JLSS_NIS_INSTALL is set (to any non-empty string value). # X################################################################ X X################################################################ X# Sample installation configuration file # X################################################################ X# NB: Some variable names in the configuration file are fixed. # X# These are: envdir, envusr, envgrp, envtmp, defdir, # X# defusr, defgrp, deftmp, IN_MSG, IN_TRAP, RM_MSG, # X# RM_TRAP, PRODUCT, FILELIST # X# Other variables can be defined to suit the installation. # X# eg for FGLGEN, FGLGENBIN can be defined and exported for use # X# by the customisation script. The environment variables in # X# IN_MSG etc could be spelt out literally (eg SCCSDIR instead # X# of $envdir), but envdir etc must be set. # X################################################################ X# X#envdir=SCCSDIR X#defdir=/usr/local X#envusr=SCCSUSR X#defusr=bin X#envgrp=SCCSGRP X#defgrp=bin X#envtmp=SCCSTMP X#deftmp=${TMPDIR:-/tmp}/jlss X# X#PRODUCT="SCCS ToolKit Version 1 (1992-12-29)" X# X#IN_MSG=' X#echo " Base Directory: $envdir=$DIR" X#echo " Owner: $envusr=$USR" X#echo " Group: $envgrp=$GRP" X#echo "" X#echo "The executables will go in $envdir/bin" X#echo "The documentation will go in $envdir/doc" X#echo "The other files will go in $envdir/etc" X#' X# X#IN_TRAP=" X#echo 'Set: $envdir to define the location of the programs' X#echo ' $envusr to define the owner' X#echo ' $envgrp to define the group' X#trap 0 X#exit 1" X# X#RM_MSG=' X#echo " Base Directory: $envdir=$DIR" X#echo " Owner: $envusr=$USR" X#echo " Group: $envgrp=$GRP" X#echo "" X#echo "The executables were placed in $envdir/bin" X#echo "The documentation were placed in $envdir/doc" X#echo "The other files were placed in $envdir/etc" X#' X# X#RM_TRAP=" X#echo 'Set: $envdir to define the location of the programs' X#echo ' $envusr to define the owner' X#echo ' $envgrp to define the group' X#echo ' $envtmp to define where the files are to be moved to' X#trap 0 X#exit 1" X# X#FILELIST=etc/sccs.lst X################################################################ X X####################### X# Check authorisation # X####################### X Xarg0=`basename $0 .sh` Xuid=`id | sed 's/uid=\([0-9][0-9]*\)[^0-9].*/\1/'` Xcase "$uid" in X0) : OK;; X*) echo "$arg0: You must be root to install this software" >&2 X exit 1;; Xesac X X############# X# Functions # X############# X Xusage(){ X echo "Usage: $arg0 [install|uninstall] product" >&2 X exit 1 X} X Xconfig(){ X error "fault in configuration file $config" X} X Xerror(){ X { X echo "$arg0: $*" X echo "$arg0: please report this to your supplier" X echo X [ -z "$PRODUCT" ] && echo "*** $MODE failed ***" X [ -n "$PRODUCT" ] && echo "*** $MODE of $PRODUCT failed ***" X echo X } >&2 X exit 1 X} X Xmkpath(){ X # Make all directories leading to named directory X echo $file | X awk -F/ '{ string = ""; X # $1 is empty X for (i = 2; i <= NF; i++) { X string = string "/" $i; X print string; X } X }' | X while read directory X do X if [ ! -d $directory ] X then X mkdir $directory X chmod $perms $directory X chgrp $group $directory X chown $owner $directory X fi X done X} X Xchk_usrgrp(){ X if grep "^$USR:" /etc/passwd >/dev/null X then : OK X else echo "User $USR does not exist in /etc/passwd" >&2 X exit 1 X fi X if grep "^$GRP:" /etc/group >/dev/null X then : OK X else echo "Group $GRP does not exist in /etc/group" >&2 X exit 1 X fi X} X X################### X# Check arguments # X################### X Xcase $# in X2) case $1 in X install) MODE=Installation;; X uninstall) MODE=Uninstallation;; X *) usage;; X esac;; X*) usage;; Xesac X XPATH=$PATH:.:etc Xexport PATH X X############################# X# Locate configuration file # X############################# X Xconfig=$2.ins Xif [ -f $config -a -r $config ] Xthen : OK Xelif [ -f etc/$config -a -r etc/$config ] Xthen : OK Xelse X echo "$arg0: cannot locate configuration file $config for ${1}ing $2" >&2 X exit 1 Xfi X X########################### X# Read configuration file # X########################### X X# Ensure that we don't get affected by stray environment variables XFILELIST= XDIR= XUSR= XGRP= XTMP= XPRODUCT= XIN_MSG= XRM_MSG= XRM_TRAP= XIN_TRAP= Xenvdir= Xenvgrp= Xenvusr= Xenvtmp= Xdefdir= Xdefgrp= Xdefusr= Xdeftmp= X X. $config X X####################### X# Check configuration # X####################### X X[ -z "$envdir" ] && config X[ -z "$envgrp" ] && config X[ -z "$envusr" ] && config X[ -z "$envtmp" ] && config X[ -z "$defdir" ] && config X[ -z "$defgrp" ] && config X[ -z "$defusr" ] && config X[ -z "$deftmp" ] && config X Xeval "DIR=\${$envdir:=$defdir}" Xeval "USR=\${$envusr:=$defusr}" Xeval "GRP=\${$envgrp:=$defgrp}" Xeval "TMP=\${$envtmp:=$deftmp}" X X# Yes, the $ characters really are required! Xexport $envdir $envusr $envgrp $envtmp X X[ -z "$FILELIST" ] && config X[ -z "$IN_MSG" ] && config X[ -z "$IN_TRAP" ] && config X[ -z "$PRODUCT" ] && config X[ -z "$RM_MSG" ] && config X[ -z "$RM_TRAP" ] && config X X################################# X# Installation & Uninstallation # X################################# Xif [ $MODE = Installation ] Xthen X X echo "" X echo "" X echo "$MODE of $PRODUCT" X echo "" X echo "The software will be installed as follows:" X echo "" X eval "$IN_MSG" X echo "" X echo "If this is incorrect, hit the INTERRUPT key." X echo "If this is correct, hit the RETURN key." X echo "" X echo "" X X trap "$IN_TRAP" 0 2 3 X read x || exit X echo X trap 0 2 3 X X if [ -z "$JLSS_NIS_INSTALL" ] X then chk_usrgrp X fi X X echo "$MODE of $PRODUCT started...\c" X sleep 5 X echo "" X echo "" X X # Install programs and files X sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' $FILELIST | X while read file type link owner group perms X do X if [ $owner = - ] ; then owner=$USR ; fi X if [ $group = - ] ; then group=$GRP ; fi X case "$type" in X directory) X dirlist="$file $dirlist" X file=$DIR/$file X echo "Installing directory $file" X [ -d $file ] || mkpath $file X ;; X deleted) X rm -f $DIR/$file X ;; X link) X file=$DIR/$file X link=$DIR/$link X [ -f $link ] || error "missing link file $link" X rm -f $file X ln $link $file X ;; X symlink) X file=$DIR/$file X link=$DIR/$link X [ -f $link ] || error "missing link file $link" X rm -f $file X ln -s $link $file X ;; X file) X [ -f $file ] || error "$file not found" X dname=$DIR/`dirname $file` X [ -d $dname ] || error "$dname is not a directory" X mv $file tmp.$$ # Save file (in case it is already in situ) X rm -f $DIR/$file # Remove existing destination file (if any) X mv tmp.$$ $DIR/$file # Store new file in correct place X chmod $perms $DIR/$file X chgrp $group $DIR/$file X chown $owner $DIR/$file X ;; X exec) X file=$DIR/$file X if [ "$link" != "-" ] X then link=$DIR/$link X else link= X fi X [ -x $file ] || error "$file not executable" X $file $link X ;; X *) error "unknown file type $type" X ;; X esac X done X X echo "" X echo "$MODE of $PRODUCT complete" X echo "" X Xelse X X echo "" X echo "" X echo "$MODE of $PRODUCT" X echo "" X echo "The software was installed as follows:" X echo "" X eval "$RM_MSG" X echo "" X echo "The uninstalled software will be moved to:" X echo "" X echo " Junk Directory: $envtmp=$TMP" X echo "" X echo "If this is incorrect, hit the INTERRUPT key." X echo "If this is correct, hit the RETURN key." X echo "" X echo "" X X trap "$RM_TRAP" 0 2 3 X read x || exit X echo X trap 0 2 3 X X chk_usrgrp X X echo "$MODE of $PRODUCT started...\c" X sleep 5 X echo "" X echo "" X X # Uninstall programs and files X sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' $FILELIST | X { X while read file type link owner group perms X do X if [ $owner = - ] ; then owner=$USR ; fi X if [ $group = - ] ; then group=$GRP ; fi X case "$type" in X directory) X dirlist="$DIR/$file $dirlist" X file=$TMP/$file X echo "Creating directory $file" X [ -d $file ] || mkpath $file X ;; X deleted|exec) X : OK X ;; X file|link) X ifile=$DIR/$file X jfile=$TMP/$file X [ -f $ifile ] && mv $ifile $jfile X ;; X *) X error "unknown file type $type" X ;; X esac X done X rmdir $dirlist 2>/dev/null X } X X echo "" X echo "$MODE of $PRODUCT complete" X echo "" X echo "Remember to remove the software from $TMP as soon as convenient" X echo "" X Xfi SHAR-EOF chmod 444 jlss.sh if [ `wc -c mkbod.sh <<'SHAR-EOF' X: "$Id: mkbod.sh,v 1.3 1992/05/10 17:43:32 jl Exp $" X# X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# X# Make Binary-Only Distribution X Xarg0=`basename $0 .sh` X Xif [ $# -ne 3 ] Xthen X echo "Usage: $arg0 source object bod-file" >&2 X exit 1 Xfi X XSOURCEDIR=${1} XOBJECTDIR=${2} X Xsed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' ${3} | X{ Xstatus=0 Xwhile read dist comp Xdo X X case $dist in # Handle variable setting lines X *=*) eval $dist $comp X continue;; X esac X X eval target=$OBJECTDIR/$dist X if [ ! -f $target ] X then X tgtdir=`dirname $target` X [ -d $tgtdir ] || mkpath $tgtdir X echo $target X eval comp=$comp X case $comp in X /*) # Absolute X if [ ! -f $comp ] X then X echo "$arg0: cannot find $comp" >&2 X status=1 X continue X fi X cp $comp $target X ;; X *) # Relative X eval source=$SOURCEDIR/$comp X if [ ! -f $source ] X then X echo "$0: cannot find $source" >&2 X status=1 X continue X fi X if [ $source != $target ] X then X cp $source $target X fi X ;; X esac X fi X Xdone Xexit $status X} SHAR-EOF chmod 444 mkbod.sh if [ `wc -c mkinfxdir.1 <<'SHAR-EOF' XUsage: Xmkinfxdir [-I /new/informixdir] -E /informix/engines -T /informix/tools \ X [-cdfglnopsv] [-F filelist] X XThe new INFORMIXDIR defaults to the current directory but can be specified Xby the '-I' option. The new directory need not exist; it is created using X'mkdir -p' if necessary. This can be overridden by setting MKDIR in the Xenvironment. X XThe Engines software (OnLine, SE, I-Net, I-Star and ESQL/C) will be taken Xfrom the directory specified by the '-E' option. The Tools software (I4GL, XI4GL-RDS, I4GL-ID, ISQL) will be collected from the directory specified by Xthe '-T' option. X XThe flags '-c' and '-l' are mutually exclusive and stand for copy and link Xrespectively. The software will be linked (symbolically) by default, but Xcan be copied. The '-f' option forcibly overwrites any existing files Xunder the new INFORMIXDIR. The '-d' option includes demo programs and Xdirectories; they are excluded by default. The '-v' option is verbose and Xdetails what it is doing for each file. The '-n' option does not actually Xexecute the commands. The '-s' option silences the commands. X XThe '-F' option can be used to override the built in product list by Xspecifying the product file lists to be used. The command handles the Xpossibility that I-Net and I-Star are not relevant in 6.00 and later Xversions. It also sequences the operations correctly -- Tools are Xinstalled before Engines before Networking. X XIf none of the flags from the set '-cdflnsv' are specified, the command Xuses '-ldv'. However, this can lead to minor problems; using the '-f' flag Xmeans that a later version of a file will replace an earlier version. You Xare therefore encouraged to use '-lf' options, possibly with '-v' and '-d'. XThe '-g', '-o' and '-p' options are passed through to ixcreate to suppress Xsetting group, owner and permissions respectively. X X--------------------------------------------------------------------------- X XTypically, the following sequence will create a new INFORMIXDIR for someone, Xusing the 5.04.UC1 Engines and 4.13.UD1 Tools: X Xmkinfxdir -lvdf -I /usr/informix/5.04.UC1 -E /informix/5.04.UC1 \ X -T /informix/4.13.UD1 SHAR-EOF chmod 444 mkinfxdir.1 if [ `wc -c mkinfxdir.sh <<'SHAR-EOF' X: "@(#)$Id: mkinfxdir.sh,v 1.3 1996/06/20 15:47:34 johnl Exp $" X# X# Create a new INFORMIXDIR from pre-installed software. X# X# * Should be run by root as ixcreate uses chown to set permissions. X# * The software is assumed to be installed in the remote directories with X# the correct permissions if symbolic links (the default) are used. X# * If invoked with no filelist arguments, it installs I4GL, I4GL-RDS, X# I4GL-ID, ISQL, OnLine, SE, ESQL/C (and I-Star and I-Net if available). X Xarg0=`basename $0 .sh` Xusage="Usage: $arg0 [-I informixdir] [-T toolsdir] [-E enginedir] [-F filelist] [-cdfglnopsv]" X X: ${IXCREATE:=ixcreate} X: ${MKDIR:="mkdir -p"} XENGINES=${INFORMIXDIR:-/usr/informix} XTOOLS=${INFORMIXDIR:-/usr/informix} XINFX=. XSFLAGS= Xfilelist= X Xset -- `getopt cdfglnopsvE:T:I:F: ${@:+"$@"}` X Xwhile [ $# -gt 0 ] Xdo X case "$1" in X --) shift X break;; X -c) SFLAGS="${SFLAGS}c";; X -d) SFLAGS="${SFLAGS}d";; X -f) SFLAGS="${SFLAGS}f";; X -g) SFLAGS="${SFLAGS}g";; X -l) SFLAGS="${SFLAGS}l";; X -n) SFLAGS="${SFLAGS}n";; X -o) SFLAGS="${SFLAGS}o";; X -p) SFLAGS="${SFLAGS}p";; X -s) SFLAGS="${SFLAGS}s";; X -v) SFLAGS="${SFLAGS}v";; X -I) INFX=$2 X shift;; X -E) ENGINES=$2 X shift;; X -T) TOOLS=$2 X shift;; X -F) filelist="$filelist $2" X shift;; X *) echo "$usage" >&2 X exit 1;; X esac X shift Xdone X Xif [ $# -gt 0 ] Xthen X echo "$usage" >&2 X exit 1 Xfi X Xif [ ! -d $ENGINES ] Xthen X echo "$arg0: engines 'directory' $ENGINES isn't a directory" >&2 X exit 1 Xelif [ ! -d $TOOLS ] Xthen X echo "$arg0: tools 'directory' $TOOLS isn't a directory" >&2 X exit 1 Xfi X Xif [ -d $INFX ] Xthen : OK Xelif $MKDIR $INFX Xthen : OK Xelse error "$arg0: unable to create new INFORMIXDIR $INFX" Xfi X Xif [ -z "$filelist" ] Xthen X filelist="nefiles fglfiles fgpfiles fgldbfiles sqlfiles X onlinefiles sefiles esqlfiles X netfiles starfiles" Xfi X Xif [ -z "$SFLAGS" ] Xthen SFLAGS=ldv Xfi X Xfor file in $filelist Xdo X case $file in X fglfiles) r=$TOOLS;; X fgpfiles) r=$TOOLS;; X fgldbfiles) r=$TOOLS;; X sqlfiles) r=$TOOLS;; X nefiles) r=$TOOLS;; X onlinefiles) r=$ENGINES;; X sefiles) r=$ENGINES;; X esqlfiles) r=$ENGINES;; X netfiles|starfiles) X if [ -f $ENGINES/etc/$file ] X then r=$ENGINES X else X # Suppress -- 6.0x installation assumed X continue X fi;; X *) if [ -f $ENGINES/etc/$file ] X then r=$ENGINES X elif [ -f $TOOLS/etc/$file ] X then r=$TOOLS X else X echo "$arg0: unknown product file $file" >&2 X continue X fi;; X esac X echo "$IXCREATE -$SFLAGS -L $INFX -R $r -F $file" Xdone | Xawk '{ if ($6 == oldsrc) { cmd = cmd " -F " $8; } X else { print cmd; oldsrc = $6; cmd = $0; } X } XEND { print cmd; }' | Xsh -x SHAR-EOF chmod 444 mkinfxdir.sh if [ `wc -c mkixcpio.1 <<'SHAR-EOF' X.\" @(#)$Id: mkixcpio.1,v 1.1 1997/02/10 14:36:53 johnl Exp $ X.\" @(#)Manual page: Informix Install Utilities X.ds fC "Version: $Revision: 1.1 $ ($Date: 1997/02/10 14:36:53 $) X.TH PROG 1S "JLSS Informix Tools" X.SH NAME Xmkixcpio \(em recreate cpio archive of Informix product X.SH SYNOPSIS X\fBmkixcpio\fP [-adnsvV] [-F filelist] [-I informixdir] X.SH DESCRIPTION XUse mkixcpio to create a cpio archive containing the files specified in the Xofficial files list(s), writing the resulting cpio (character-mode) archive Xto standard output. X.P XThe \-a, \-v and \-V options are passed to cpio, where they mean 'reset Xaccess times after copying', 'verbose' (print each file name as it is Xprocessed), and 'special verbose' (print a period `.' for each file name Xprocessed). X.P XThe \-n option means do not execute cpio and gives a list of the file names Xwhich would be copied. X.P XThe \-d option means do not include demo-related files (names which contain X'demo'). XUsing this means that the product will not install without errors, but this Xis sometimes acceptable. X.P XThe \-s option means operate silently. XNormally, mkixcpio prints details of what it is doing on stderr; the \-s Xoption suppresses this output. XNote that the \-v (or \-V) option makes cpio verbose, regardless of whether Xthe \-s option is set. X.P XThe source material is found in $INFORMIXDIR unless this is overridden Xon the command line by the \-I option. X.P XOne or more \-F options can be specified. XThe named files can be relative names, in which case they are looked for Xin $INFORMIXDIR/etc, or they can absolute names, in which case they must correspond Xto an actual file. XIf no \-F options are specified, all the names ending with 'files' in the X$INFORMIXDIR are used. X.P XThe cpio command should be forced to follow symbolic links (to copy the Xcontents of the file the link points to), rather than Xsimply creating symlinks matching the ones in $INFORMIXDIR. XOn SVR4 Unix machines, this is done with the \-L option; Xsetting environment variable MKIXCPIO_FOLLOWSYMLINKS can override this. X.SH FILES X.SH "SEE ALSO" X.SH DIAGNOSTICS X.SH BUGS XFiles placed in system directories or removed by the Informix install Xprocess are probably mishandled. X.SH AUTHOR XJonathan Leffler X.br XJLSS X.br X10th February 1997 SHAR-EOF chmod 444 mkixcpio.1 if [ `wc -c mkixcpio.sh <<'SHAR-EOF' X: "@(#)$Id: mkixcpio.sh,v 1.2 1997/02/10 14:36:41 johnl Exp $" X# X# (Re)Create CPIO file from Informix Installation X# X# CPIO file written to stdout X X# cpio must be made follow any symbolic links, not just copy the X# contents of the link itself. Default correct for SVR4. X: ${MKIXCPIO_FOLLOWSYMLINKS='L'} X Xarg0=`basename $0 .sh` Xusage="Usage: $arg0 [-I informixdir] [-F filelist] [-adnsvV]" X: ${INFORMIXDIR:=/usr/informix} X Xcpioflags="-ocB${MKIXCPIO_FOLLOWSYMLINKS}" Xremovedemo="" Xexecute=yes Xsilent=no X Xerror(){ X echo "$*" >&2 X exit 1 X} X Xusage(){ X error "$usage" X} X Xset -- `getopt adnsvVF:I: ${@:+"$@"}` X Xwhile [ $# -gt 0 ] Xdo X case "$1" in X --) shift; break;; X -a) cpioflags="${cpioflags}a";; X -d) removedemo="-e /demo/d";; X -n) execute=no;; X -s) silent=yes;; X -v) cpioflags="${cpioflags}v";; X -V) cpioflags="${cpioflags}V";; X -F) filelist="$filelist $2"; shift;; X -I) INFORMIXDIR=$2; shift;; X *) usage;; X esac X shift Xdone X Xif [ $# -gt 0 ] Xthen usage Xfi X X# On Solaris, in both Bourne and Korn shell, the -d operator will follow X# any symlinks and check the real file at the far end. This also applies X# to almost all the other test operators that check the file type, except X# for the test operators -h or -L which explicitly test for symlinks. Xif [ ! -d $INFORMIXDIR ] Xthen error "$arg0: 'directory' $INFORMIXDIR isn't a directory" Xfi X Xif [ -z "$filelist" ] Xthen filelist=`cd $INFORMIXDIR/etc; ls *files 2>/dev/null` Xfi X Xfiles="" Xfor file in $filelist Xdo X case $file in X /*) nfile=$file;; X *) nfile=$INFORMIXDIR/etc/$file;; X esac X if [ -r $nfile ] X then files="$files $nfile" X else error "$arg0: cannot locate $nfile" X fi Xdone X Xif [ -z "$files" ] Xthen error "$arg0: $INFORMIXDIR/etc does not contain any files lists" Xfi X Xif [ $silent = no ] Xthen X { X rmd=${removedemo-' -- demo files omitted'} X echo "Creating CPIO file with options $cpioflags$rmd" X echo "Reference INFORMIXDIR is $INFORMIXDIR" X sed -n '/^PRODUCT/s/PRODUCT[ ]*//p' $files X } 1>&2 Xfi X X# Select all file/directory entries and sort uniquely Xsed -e 's/#.*//' -e '/^[ ]*$/d' -e '/^PRODUCT/d' -e '/^NAME/d' \ X -e 's/[ ].*//' $removedemo $files | Xsort -u | X Xif [ $execute = yes ] Xthen cd $INFORMIXDIR; cpio $cpioflags Xelse cat - Xfi SHAR-EOF chmod 444 mkixcpio.sh if [ `wc -c mkpath.sh <<'SHAR-EOF' X: "$Id: mkpath.sh,v 1.6 1992/05/10 17:43:35 jl Exp $" X# X# @(#)JLSS Informix Administration Tools Version 2 (1997-05-12) X# X# Make all directories down to named directory X Xarg0=`basename $0 .sh` Xusage(){ Xecho "Usage: $arg0 [-o owner] [-g group] [-p perms] directory [...]" >&2 Xexit 1 X} X Xset -- `getopt o:g:p: "$@"` X Xwhile [ $# -gt 0 ] Xdo X case $1 in X --) shift; break;; X -o) owner=$2;; X -g) group=$2;; X -p) perms=$2;; X -*) usage;; X *) break;; X esac X shift 2 Xdone X Xcase $# in X0) usage;; Xesac X Xfor directory in $* Xdo X echo $directory Xdone | Xawk -F/ ' { string="" X pad="" X for (i = 1; i <= NF; i++) { X string=string pad $i X if (string != "") print string X pad="/" X } X }' | Xsort -u | Xwhile read directory Xdo X if [ ! -d $directory ] X then X mkdir $directory X [ -z "$perms" ] || chmod $perms $directory X [ -z "$group" ] || chgrp $group $directory X [ -z "$owner" ] || chown $owner $directory X fi Xdone SHAR-EOF chmod 444 mkpath.sh if [ `wc -c ods.rc <<'SHAR-EOF' X: "@(#)$Id: ods.rc,v 1.1 1997/05/12 11:38:54 johnl Exp $" X# X# Control script for Informix-OnLine Dynamic Server X# X# * Edit INFORMIXDIR, INFORMIXSERVER and ONCONFIG to match your system. X# * Install under /etc, possibly in /etc/init.d with links in /etc/rcN.d, X# or possibly listing it in /etc/inittab. X XINFORMIXDIR=/usr/informix Xexport INFORMIXDIR XPATH=$INFORMIXDIR/bin:$PATH Xexport PATH XINFORMIXSERVER=online Xexport INFORMIXSERVER XINFORMIXSQLHOSTS=$INFORMIXDIR/etc/sqlhosts Xexport INFORMIXSQLHOSTS XONCONFIG=onconfig.online Xexport ONCONFIG X Xcase "$1" in Xstart) X echo "Starting Informix-OnLine Dynamic Server ($INFORMIXSERVER)" X onstat -V X oninit || echo "*** FAILED TO START $INFORMIXSERVER ***" X ;; Xstop) X if onstat -p > /dev/null X then X echo "Stopping Informix-OnLine Dynamic Server ($INFORMIXSERVER)" X onmode -ky || echo "*** FAILED TO STOP $INFORMIXSERVER ***" X else X echo "Informix-OnLine Dynamic Server ($INFORMIXSERVER) not running" X fi X ;; X*) X echo "Usage: $0 { start | stop }" 1>&2 X exit 1 X ;; Xesac X SHAR-EOF chmod 444 ods.rc if [ `wc -c stderr.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: stderr.c,v $ X@(#)Version: $Revision: 6.9 $ X@(#)Last changed: $Date: 1997/04/29 11:46:23 $ X@(#)Purpose: Error reporting routines -- using stdio X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1988-91,1996-97 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X#include X#include X#include X#include X#include "stderr.h" X Xstatic char arg0[15] = "**undefined**"; X X#ifndef lint Xstatic const char sccs[] = "$Id: stderr.c,v 6.9 1997/04/29 11:46:23 johnl Exp $"; X#endif /* lint */ X Xconst char *getarg0(void) X{ X return(arg0); X} X Xvoid remark2(const char *s1, const char *s2) X{ X err_report(ERR_REM, ERR_STAT, "%s %s\n", (s1), (s2)); X} X Xvoid remark(const char *s1) X{ X err_report(ERR_REM, ERR_STAT, "%s\n", (s1)); X} X Xvoid error2(const char *s1, const char *s2) X{ X err_report(ERR_ERR, ERR_STAT, "%s %s\n", (s1), (s2)); X} X Xvoid error(const char *s1) X{ X err_report(ERR_ERR, ERR_STAT, "%s\n", (s1)); X} X Xvoid stop(const char *s1) X{ X err_report(ERR_ABT, ERR_STAT, "%s\n", (s1)); X} X Xvoid usage(const char *s1) X{ X err_report(ERR_USE, ERR_STAT, (s1)); X} X Xvoid version(const char *s1, const char *s2) X{ X err_report(ERR_ERR, EXIT_SUCCESS, "%s Version %s\n", (s1), (s2)); X} X X/* Store basename of command, excluding trailing slashes */ X/* Doesn't handle two pathological cases -- "/" and "" */ Xvoid setarg0(const char *argv0) X{ X const char *cp; X size_t nbytes = sizeof(arg0) - 1; X X if ((cp = strrchr(argv0, '/')) != (char *)0 && *(cp + 1) == '\0') X { X /* Skip backwards over trailing slashes */ X const char *ep = cp; X while (ep > argv0 && *ep == '/') X ep--; X /* Skip backwards over non-slashes */ X cp = ep; X while (cp > argv0 && *cp != '/') X cp--; X cp++; X nbytes = ep - cp + 1; X if (nbytes > sizeof(arg0) - 1) X nbytes = sizeof(arg0) - 1; X } X else if (cp != (char *)0) X { X /* Regular pathname containing slashes */ X cp++; X } X else X { X /* Basename of file only */ X cp = argv0; X } X strncpy(arg0, cp, nbytes); X arg0[nbytes] = '\0'; X} X Xvoid err_report(int flags, int estat, const char *string,...) X{ X va_list args; X X va_start(args, string); X X if (flags & ERR_FLUSH) X (void)fflush(stdout); X if (flags & ERR_USAGE) X (void)fprintf(stderr, "Usage: %s %s\n", arg0, string); X else if (flags & ERR_COMM) X { X (void)fprintf(stderr, "%s: ", arg0); X (void)vfprintf(stderr, string, args); X } X if (flags & ERR_ABORT) X abort(); X if (flags & ERR_EXIT) X exit(estat); X} X X#ifdef TEST X Xstatic const char *list[] = X{ X "/usr/fred/bloggs", X "/usr/fred/bloggs/", X "/usr/fred/bloggs////", X "bloggs", X "/.", X ".", X "/", X "//", X "///", X "////", X "", X (char *)0 X}; X Xint main(int argc, char **argv) X{ X const char **name; X char *data; X X setarg0(argv[0]); X remark("testing values for argv[0]"); X X for (name = list; *name != (char *)0; name++) X { X data = malloc(strlen(*name) + 1); X strcpy(data, *name); X printf("name = <<%s>>; ", *name); X setarg0(*name); X printf(" (<<%s>>) arg0 = <<%s>>\n", *name, getarg0()); X free(data); X } X X setarg0(argv[0]); X remark("reporting arguments to program"); X while (*++argv != (char *)0) X remark2("next argument", *argv); X return(0); X} X X#endif /* TEST */ SHAR-EOF chmod 444 stderr.c if [ `wc -c stderr.h <<'SHAR-EOF' X/* X@(#)File: $RCSfile: stderr.h,v $ X@(#)Version: $Revision: 6.8 $ X@(#)Last changed: $Date: 1997/04/29 11:47:03 $ X@(#)Purpose: Header file for standard error functions X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1989-93,1996-97 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X#ifndef STDERR_H X#define STDERR_H X X#ifdef MAIN_PROGRAM X#ifndef lint Xstatic const char stderr_h[] = "$Id: stderr.h,v 6.8 1997/04/29 11:47:03 johnl Exp $"; X#endif X#endif X X/* -- Definitions for error handling */ X X#define ERR_STAT (1) /* Default exit status */ X X#define ERR_COMM (0x01) /* Print message on stderr */ X#define ERR_USAGE (0x02) /* Print usage on stderr */ X#define ERR_EXIT (0x04) /* Exit -- do not return */ X#define ERR_ABORT (0x08) /* Abort -- do not return */ X#define ERR_FLUSH (0x10) /* Flush stdout */ X X/* -- Standard combinations of flags */ X X#define ERR_USE (ERR_USAGE|ERR_EXIT|ERR_FLUSH) X#define ERR_REM (ERR_COMM|ERR_FLUSH) X#define ERR_ERR (ERR_COMM|ERR_EXIT|ERR_FLUSH) X#define ERR_ABT (ERR_COMM|ERR_ABORT|ERR_FLUSH) X X/* -- Global definitions */ X Xextern const char *getarg0(void); X Xextern void err_report(int flags, int estat, const char *string, ...); Xextern void error(const char *s1); Xextern void error2(const char *s1, const char *s2); Xextern void remark(const char *s1); Xextern void remark2(const char *s1, const char *s2); Xextern void setarg0(const char *argv0); Xextern void stop(const char *s1); Xextern void usage(const char *s1); Xextern void version(const char *s1, const char *s2); X X#endif /* STDERR_H */ SHAR-EOF chmod 444 stderr.h if [ `wc -c tokenise.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: tokenise.c,v $ X@(#)Version: $Revision: 1.3 $ X@(#)Last changed: $Date: 1991/12/22 23:05:18 $ X@(#)Purpose: Tokenise a string X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1991 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X/* X** 1. A token is 0 or more characters followed by a terminator or separator. X** The terminator is ASCII NUL '\0'. The separators are user-defined. X** 2. A leading separator is preceded by a zero-length token. X** A trailing separator is followed by a zero-length token. X** 3. The number of tokens found is returned. X** The list of token pointers is terminated by a NULL pointer. X** 4. The routine returns 0 if the arguments are invalid. X** It returns -1 if too many tokens were found. X*/ X X#include X X#define NO 0 X#define YES 1 X X#define IS_SEPARATOR(c,s,n) (((c) == *(s)) || ((n) > 1 && strchr((s),(c)))) X#define DIM(x) (sizeof(x)/sizeof(*(x))) X#define NIL(x) ((x)0) X X#ifndef lint Xstatic char sccs[] = "$Id: tokenise.c,v 1.3 1991/12/22 23:05:18 jl Exp $"; X#endif X Xint tokenise(str, sep, token, maxtok, nulls) Xchar *str; /* InOut: String to be tokenised */ Xchar *sep; /* In: Token separators */ Xchar *token[]; /* Out: Pointers to tokens */ Xint maxtok; /* In: Maximum number of tokens */ Xint nulls; /* In: Are multiple separators OK? */ X{ X int c; X int n_tokens; X int tokenfound; X int n_sep = strlen(sep); X X if (n_sep <= 0 || maxtok <= 2) X return(0); X X n_tokens = 1; X *token++ = str; X while ((c = *str++) != '\0') X { X tokenfound = NO; X while (c != '\0' && IS_SEPARATOR(c, sep, n_sep)) X { X tokenfound = YES; X *(str - 1) = '\0'; X if (nulls) X break; X c = *str++; X } X if (tokenfound) X { X if (++n_tokens >= maxtok - 1) X return(-1); X if (nulls) X *token++ = str; X else X *token++ = str - 1; X } X if (c == '\0') X break; X } X *token++ = NIL(char *); X return(n_tokens); X} X X#ifdef TEST X Xstruct X{ X char *sep; X int nulls; X} data[] = X{ X "/.", 0, X "/.", 1, X "/", 0, X "/", 1, X ".", 0, X ".", 1, X "", 0 X}; X Xchar string[] = "/fred//bill.c/joe.b/"; X Xmain() X{ X int i; X int j; X int n; X char input[100]; X char *token[20]; X X for (i = 0; i < DIM(data); i++) X { X strcpy(input, string); X printf("\n\nTokenising <<%s>> using <<%s>>, null %d\n", X input, data[i].sep, data[i].nulls); X n = tokenise(input, data[i].sep, token, DIM(token), X data[i].nulls); X printf("Return value = %d\n", n); X for (j = 0; j < n; j++) X printf("Token %d: <<%s>>\n", j, token[j]); X if (n > 0) X printf("Token %d: 0x%08X\n", n, token[n]); X } X return(0); X} X X#endif /* TEST */ SHAR-EOF chmod 444 tokenise.c if [ `wc -c unixwarn.sh <<'SHAR-EOF' X: "@(#)$Id: unixwarn.sh,v 1.1 1993/06/13 00:54:15 jl Exp $" X# X# Print a list of processes which have used more than X cpu minutes X# Be careful with the quotes in the AWK script. Additionally, in ASCII, X# ORD(':') = 58; ORD('0') = 48; ORD('9') = 57; ORD('.' ) = 46. X# This means that "1:00" > "10:00", which is undesirable. X# Hence the conversion of ':' to '.' which avoids this problem. X XX=${1:-"10:00"} XX=`echo $X | sed 's/:/./'` X Xn=`ps -e | sed 's/:/./' | Xawk '{if ($3 > "'$X'" && $3 != "TIME") {printf("%s%s",pad,$1); pad=",";}} XEND {printf"\n";}'` X Xif [ -n "$n" ] Xthen ps -fp $n | ixmail -s "Expensive processes" Xfi SHAR-EOF chmod 444 unixwarn.sh if [ `wc -c vstrcpy.c <<'SHAR-EOF' X/* X@(#)File: $RCSfile: vstrcpy.c,v $ X@(#)Version: $Revision: 1.9 $ X@(#)Last changed: $Date: 1997/04/29 14:36:22 $ X@(#)Purpose: Copy/concatenate variable number of strings X@(#)Author: J Leffler X@(#)Copyright: (C) JLSS 1988-89,1991,1995,1997 X@(#)Product: JLSS Informix Administration Tools Version 2 (1997-05-12) X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X/* X** vstrcpy(dst, n, src1, src2, ...); X** X** Vstrcpy copies each of its arguments src1, src2, ... into dst X** and null terminates the string. If given the value n = 0, it X** simply copies a null into dst[0]. X** Vstrcpy assumes that there is enough space in dst to contain X** the strings src1, src2, ... X** concatenated together. X** Vstrcpy returns a pointer to the terminal null. X*/ X X#include X#include "jlss.h" X X#ifndef lint Xstatic const char sccs[] = "$Id: vstrcpy.c,v 1.9 1997/04/29 14:36:22 johnl Exp $"; X#endif X Xchar *vstrcpy(char *dst, int n, ...) X{ X const char *src; X int i; X va_list args; X X va_start(args, n); X X for (i = 0; i < n; i++) X { X src = va_arg(args, const char *); X while ((*dst = *src++) != '\0') X dst++; X } X *dst = '\0'; X va_end(args); X return(dst); X} X X#ifdef TEST X X#include X#include X#include X Xstatic char *nested(char *s, int n) X{ X char *t = s; X X puts("Nested"); X while (n-- > 0) X { X t = nested(t, n); X puts(s); X } X t = vstrcpy(t, 2, "\ngoogleplex", " widget"); X return(t); X} X X/* Measurement shows that 199 bytes are necessary */ Xint main(void) X{ X char *buff; X char *cp; X X if ((buff = malloc(200)) == 0) X { X puts("memory allocation failed (dammit)"); X exit(1); X } X X cp = vstrcpy(buff, 5, "elephants", " ", "get arthritis", " ", "too easily!"); X puts(buff); X cp = vstrcpy(cp, 1, "\nelegance incarnate"); X puts(buff); X cp = vstrcpy(cp, 0); X puts(buff); X cp = nested(cp, 3); X puts(buff); X printf("Length: %ld\n", (long)strlen(buff)); X free(buff); X return(0); X} X X#endif /* TEST */ SHAR-EOF chmod 444 vstrcpy.c if [ `wc -c