head     1.2;
branch   ;
access   ;
symbols  ;
locks    ;
comment  @# @;


1.2
date     92.03.25.09.29.47;  author bin;  state Exp;
branches ;
next     1.1;

1.1
date     92.02.28.11.15.30;  author bin;  state Exp;
branches ;
next     ;


desc
@@


1.2
log
@update by cef to cover bedaemon and lock
@
text
@
libmisc.a is a miscellaneous collection of useful functions
for C programmers.

misc.h	A header file with externs and #define's for the
	various functions in libmisc.a

char * alloc(n) unsigned n;
	malloc() n bytes and zero them, or put out a fatal error message.

int approx(a, b) double a, b;
	If a and b are within epsilon, then return 1; else return 0. epsilon
	is a visible double.

char * ask(reply, msg, ...) char *reply *msg;
	Print msg as a printf-style format string using any
	trailing arguments. Gets a line from stdin with gets()
	and returns the address of reply. For example:

	sscanf(ask(buff, "%d numbers", 3), &a, &b, &c);

	puts out the message "Enter: 3 numbers ", gets a reply,
	write it into buff, and hands that to sscanf().

void banner(word, pad) char *word; int pad;
	Prints word as a banner on stdout preceeded by pad
	spaces.  Each letter of the banner consists of multiple
	occurrences of itself.  You can use this to make your listings
	just the ones used by the mainframe professionals ...

int copyd(outfile, infile, length) FILE *outfile, *infile; unsigned long length;
	Copy data from one file to another for a length.
	Returns 1 on success, 0 on failure.
	If copyd cannot read the length given it will write all it can read.
	copyd usses buffers for efficiency.

unsigned short crc16(p) char *p;
	Takes the crc16 of the string p and returns it. Fast
	and perfect for hash tables, diff algorithms etc.

void fatal(msg, ...) char *msg;
	Prints msg as a printf-style format string using
	any trailing arguments.  This is proceeded by
	"\nfatal".  fatal() then calls exit(1).

char * getline(ifp, lineno) FILE *ifp; int *lineno;
	Get lines from an input file.  Returns the address of the line,
	or NULL for eof.

	lineno should usually be started at 1. lineno will
	be incremented by the number of lines in the previous call.
	Thus lineno will be the number of the line just gotten.

	# to end of line is passed. This for comments.
	\ whitespace through end of line is passed. This is for long
	  lines.
	\n newline
	\p #
	\a alarm
	\b backspace
	\r carrage return
	\f form feed
	\t tab
	\\ backslash
	\ddd octal number
	all other \ sequences are errors and reported on stderr.

void splitter(ofp, line, limit) FILE *ofp; char *line; int limit;
	Output line to ofp, splitting it into chunks less than
	limit. Inserts \ between chunks and attempts to do this
	on whitespace boundaries.  splitter produces a long line
	rather than split on non-whitespace. If line does not end in
	\n, splitter adds one.

int is_fs(special) char *special;
	Checks if a special file is a well-formed file system.
	Users should never put file systems on /dev/ram1 but
	for multi-system software, like compress, it is smart
	to test.

	Return values:
	-1	Not a device, cannot open, read or seek failed.
	 0	No filesystem.
	 1	Legal filesystem.

char * lcase(str) char *str;
	Converts str to lower case.

char * match(string, pattern, fin) char *string, *pattern, **fin;
	Like pnmatch(), except match returns the address of the
	pattern matched. fin is aimed past the end of the
	pattern found - that is, match finds a pattern and tells
	you where it is.

char *metaphone(char * word)
	Translates word to a short phonetic equivalent (4 characters
	controlled by a #define). Charles becomes XRLS. Good for looking
	up names.

char * newcpy(str) char* str;
	Create a NUL-terminated copy of str on the heap.
	It calls fatal if there is no space.

char * pathn(name, envpath, deflpath, access)
    char *name, *envpath, *deflpath, *access;
	example: pathn("helpfile", "LIBPATH", "/lib", "r")
	Look for helpfile using the environmental variable
	LIBPATH.  If that isn't set, or the second parm is NULL,
	it uses the default path "/lib".  The file found must
	have read permission.  pathn() returns the full path
	to the file found.

double picture (dble, format, output )
    double dble;    /* the number to format */
    char  *format;  /* the format mask */
    char  *output;  /* the output area. At least as large as format */

	Perform numeric formatting.  This function is superior
	to anything available under BASIC or COBOL.

	9    Provide a slot for a number.
	     5.000 passed through a mask of '999 CR' gives '005   '
	    -5.000 passed through a mask of '999 CR' gives '005 CR'
	 Note: C & R are not special to picture. Trailing non-special
	       characters print only if the number is negative

	Z    Provide a slot for a number but suppress leading zeros.
	     1034.000 passed through a mask of 'ZZZ,ZZZ' gives '  1,034'
	     Note: comma is not special to picture. Embedded non-special
	     characters print only if preceeded by significant digits
	
	J    Provide a slot for a number but shrink out lead zeros.
	     1034.000 passed through a mask of 'JJJ,JJJ' gives '1,034'
	
	K    Provide a slot for a number but shrink out any zeros.
	     70884.000 passed through a mask of 'K9/K9/K9' gives '7/8/84'
	
	$    Float a dollar sign to the front of the displayed number.
	     105.000 passed through a mask of '$ZZZ,ZZZ' gives '    $105'
	
	.    Separate the number between decimal and integer portions.
	     105.670 passed through a mask of 'Z,ZZZ.999' gives '  105.670'
	
	T    Provide a slot for a number but supresse trailing zeros.
	     105.670 passed through a mask of 'Z,ZZ9.9TT' gives '  105.67 '
	
	S    Provide a slot for a number but shrink out trailing zeros.
	     105.670 passed through a mask of 'Z,ZZ9.9SS' gives '  105.67'
	
	-    Float a - in front of negative numbers
	     105.000 passed through a mask of '-Z,ZZZ' gives '   105'
	    -105.000 passed through a mask of '-Z,ZZZ' gives '  -105'
	
	(    Act like - but prints a (
	     105.000 passed through a mask of '(ZZZ)' gives ' 105 '
	    -5.000 passed through a mask of '(ZZZ)' gives '  (5)'
	
	+    Float a + or - in front of the number depending on its sign
	     5.000 passed through a mask of '+ZZZ' gives '  +5'
	    -5.000 passed through a mask of '+ZZZ' gives '  -5'
	
	*    Fill all lead spaces to its right
	     104.100 passed through a mask of '*ZZZ,ZZZ.99' gives '*****104.10'
	     104.100 passed through a mask of '*$ZZZ,ZZZ.99' gives '*****$104.10'
	
	Any overflow is returned by picture as a double-precision number.
	    -1234.000 passed through a mask of '(ZZZ)' gives '(234)'
	     With an overflow of -1.0
	     123.400 passed through a mask of '99' gives '23'
	     With an overflow of 1.0
	     1200.000 passed through a mask of 'ZZ' gives '00'
	     With an overflow of 12.0

tm_t* jday_to_tm(jd) jday_t jd;
	Turn Julian date structure to time date structure.

time_t jday_to_time(jd) jday_t jd;
	Turn Julian date structure to COHERENT time.

void bedaemon()
	Make the caller a daemon.

	[From "The New Hacker's Dictionary":]
	daemon: /day'mn/ or /dee'mn/

	n.  A program that is not invoked explicitly, but lies dormant
	waiting for some condition(s) to occur.  The idea is that the
	perpetrator of the condition need not be aware that a daemon is
	lurking (though often a program will commit an action only because
	it knows that it will implicitly invoke a daemon.)...

	For example, when you submit a program to be
	printed with 'hpr', your file is copied to
	/usr/spool/hpd, and then the printer daemon,
	'/usr/bin/hpd' is notified that there is another
	file to print.  The advantage is that the user
	program, 'hpr', need not compete with other user
	programs for access to the printer--'/usr/bin/hpd'
	handles all access to the printer.

	Another example of a daemon in /etc/crond (or
	/etc/cron).  It spends most of its time waiting.
	When the time comes about for the next job from
	crontab, the daemon wakes up and starts the job.

	As a general rule, anything that does not interact
	directly with users can be classified as a daemon.
	Daemons do not generally generate output to a
	user's terminal.

	Any time you have a resource, like a printer or
	database, to which access should be controlled,
	you can use a daemon.  

long randl()
	Return a long random number uniformly distributed in
	1..2147483562.  This comes from "Communications of the
	ACM", vol. 31, number 6. It is the best algorithm we know
	as of this writing.
	see srandl() in this section.

char * replace(s1, pat, s3, all, matcher) char *s1, *pat, *s3, (matcher)();
	Replace one or all occurrences of pat in s1 by s3 and
	returns the result.  The definition of match is set by matcher.
	This calls the user-defined function matcher(sw, pat, &fin). The
	matcher must return the address of the pattern match; e.g.,
	its end in &fin. match() is a valid example of matcher.
	It replaces the first occurrence, or all occurrences of the
	pattern and returns the new pattern. The new pattern has been
	alloc()ed (see alloc).

showflag(data, flags, output) long data; char *flags, *output;
	Turns the bits in data to the flags in flags or '-'
	in the string output which must be as long as flags.

char * skip(s1, matcher, fin) char *s1, **fin; int (*matcher)();
	Skip one or more characters not matching some criterion
	such as isdigit().  Returns the first character skipped
	points fin at the character after the skip.

char * span(s1, matcher, fin) char *s1, **fin; int (*matcher)();
	Span one or more characters matching some criterion
	such as isdigit().  Returns the first character spanned
	points fin at the character after the span.

srandl(seed1, seed2) long seed1, seed2;
	randl() needs two seeds this sets them.  Used only
	if you need to repeat a random number sequence.

strchtr(from, to, c, def) char *from, *to; int c, def;
	Look up the char c on the string from, return the corresponding
	char on the string to if it is found otherwise return the char
	def. example: strchr("ab", "xy", c, d); if c == 'a' return
	'x', if c == 'b' return 'y' otherwise return 'd'.

strcmpl(s1, s2)
	Case-insensitive string compare.

#define strlcpy(to, from) memcpy(to, from, sizeof(to))

jday_t time_to_jday(CoherentTime) time_t CoherentTime;
	Turn COHERENT time to Julian date structure. This has days
	form 1/1/4713 BC.

jday_t tm_to_jday(tm) tm_t *tm;
	Turn tm structured date to Julian date.

void tocont()
	Prints the message "Enter <NL> to continue " and then waits for
	a new line.

ucase(s) char *s;
	Convert a string to upper case.

char * trim(s) char *s;
	Remove trailing whitespace from string s.

usage(s) char *s;
	Put out a usage: message and exit(1)

xdump(p, length) char *p;
	Make a vertical hex dump of p for length on stdout. This
	is a useful debugging tool. Vertical hex prints as 3 lines
	The top line is the display character or . if it's not
	cleanly displayable. The next two lines are the hex digit.
	The data is blocked in groups of four bytes.

xopen(filename, acs)
	Like fopen() but it calls fatal() if the open fails.

yn(question, ...) char *question;
	Ask a question with any trailing parms printf style and
	get a y or n answer. Returns a 1 for 'Y' or 'y' a 0
	for 'n' or 'N', reasks otherwise.

For an egrep style regular expression analizer see regsub.doc

The following are part of a user virtual-memory system for
COHERENT.  Sometimes users port programs such as compress to
COHERENT, which have a small number of very large arrays. Since
COHERENT is a SMALL-model operating system changes need to be
made. The following functions are intended to expedite these
changes.

void vinit(filename, ram) char *filename; unsigned ram;
	Init the virtual system using filename for work
	this may be a raw device such as /dev/rram1. ram
	is the amount of buffer space to give the system
	the more the better.

void vshutdown()
	Shut the virtual system, and make it restartable.

unsigned vopen(amt) unsigned long amt;
	Set up a virtual object.  For example, if you want to emulate having
	a 100,000-byte array and a 50,000 byte array, use
	vid1 = vopen(100000L); vid2 = vopen(50000L);
	This does some checking and tells the system that any
	reference to vid2 will be between 100000 and 150000
	on the virtual file.

char *vfind(vid, disp, dirty) unsigned vid, dirty; unsigned long disp;
	Find a character on the virtual system, mark the blocks
	dirty bit if the access is to write.  Given the example in
	vopen, if you want to find the 1000 th byte in vdi1
	c = vfind(vdi1, 1000L, 0);
	To change the 2000 th byte in vid2 to d.
	*(vfind(vid2, 2000L, 1)) = d;
	Note the dirty indicator tells the system of the change so
	that the block will be written back before it is read over.
	Blocks are 512 bytes long so int's or long's can be read
	or written without multiple accesses to vfind.

libmisc holds a number of routines with which you can lock and
unlock files and devices. It is adapted from the mechanism used by the
COHERENT implementation of UUCP.
Lock files are created in $SPOOLDIR. A lock file is given the name
LCK.resource. The lock file contains a decimal representation of the
process identifier of the process that created the lock.

It is possible to provide an alternate pid by using one of the "n"
routines. The unlocking routines regard a pid of zero as an override --
they remove the lock regardless of which process created the lock.

For a tty device, the resource is a string that consists of a decimal
representation of its major number, a decimal point, and the lower five
bits of its minor number. This conversion is done by function
gen_res_name().

Each routine takes a string that names a resource to be locked or unlocked.
The tty routines want the base name of the tty to be locked (without the
``/dev/'' part).

With the exception of gen_res_name(), all lock routines all return zero on
failure and one on success.

char *gen_res_name(tty) char *tty;
	Generate a resource name for a tty.

lockit(resource) char *resource;
	Use a resource string to lock a tty.

lockexist(resource) char *resource;
	Check whether a lock file exists for the tty with resource.

locknrm(resource, pid) char *resource; int	pid;
	Remove a lock file for a tty owned by process pid.

lockrm(resource) char *resource;
	Remove a lock file for tty with resource.

lockntty(tty, pid) char *tty; int pid;
	Lock a tty for process pid.

locktty(tty) char *tty;
	Lock a tty.

lockttyexist(tty) char *tty;
	Check whether a given tty is locked.

unlockntty(tty, pid) char *tty; int pid;
	Unlock a tty for process pid.

unlocktty(tty) char *tty;
	Unlock a tty that the current process owns.

unlockit(resource, pid) char *resource; int pid;
	Unlock something for process pid.
@


1.1
log
@Initial revision
@
text
@d180 35
d333 56
@
