[comp.os.os9] REPOST: OS9Lib Part 04/05

ocker@lan.informatik.tu-muenchen.dbp.de (Wolfgang Ocker) (10/20/88)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 5)."
# Contents:  getinfo.c man.c pw.c utmp.c perror.c setup.c
# Wrapped by weo@recsys on Tue Oct 11 14:24:14 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'getinfo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getinfo.c'\"
else
echo shar: Extracting \"'getinfo.c'\" \(6331 characters\)
sed "s/^X//" >'getinfo.c' <<'END_OF_FILE'
X/*
X *                          GETINFO for SYSINFO
X *
X *  Copyrights (c) 1988 by reccoware systems, Wolfgang Ocker, Puchheim
X *
X *
X *
X *                           IMPORTANT NOTICE
X * =====================================================================
X *
X * I  would  like to  establish the SYSINFO  concept as a  STANDARD  for
X * OS-9/68000.  So  please  DON'T CHANGE  ANYTHING.  Please send any bug
X * reports or suggestions to
X *
X *
X *            Wolfgang Ocker
X *            Lochhauserstrasse 35a
X *            D-8039 Puchheim
X *            Tel. +49 89 / 80 77 02
X *
X *            e-mail: weo@recco    (...!pyramid!tmpmbx!recco!weo)
X *                    weo@altger   (...!altnet!altger!weo)
X *                    ocker@lan.informatik.tu-muenchen.dbp.de
X *
X *
X * I will maintain the  SYSINFO package and keep it (upward) compatible!
X * You may not distribute any modified  versions, or programs which rely 
X * on a modified version.
X *
X *              If you don't like SYSINFO, don't use it!
X */
X
X/*
X * Revision history
X *
X *  #    Date     Comments                                              By
X * -------------------------------------------------------------------- ---
X * 00  09/16/88   Prepared for net release                              weo
X * 01  10/06/88   Corrected modlink parameters                          weo
X *
X */
X
X#define PATCHLEVEL 1
X
X#include <stdio.h>
X#include <strings.h>
X#include <module.h>
X#include <procid.h>
X#include <errno.h>
X#include "infomod.h"
X
Xextern int errno;
X
Xextern char *getmodname();
X
Xstatic void display_info();
Xstatic void usage();
X
Xint disp_all, disp_locks;
X
Xstatic char Copyright = "Copyrights (c) 1988 by reccoware systems puchheim";
X
X/*
X * l i n k _ i n f o _ m o d
X */
Xstatic INFO *
Xlink_info_mod()
X{
X  register mod_exec *info_module;
X
X  if ((info_module = (mod_exec *) modlink(INFO_MODULE_NAME,
X                                          mktypelang(MT_DATA, ML_ANY))) ==
X      (mod_exec *) -1)
X    return(NULL);
X
X  return((INFO *) (((char *) info_module) + info_module->_mexec));
X}
X
X/*
X * u n l i n k _ i n f o _ m o d
X */
Xstatic void 
Xunlink_info_mod()
X{
X  munload(INFO_MODULE_NAME, 0x0400);
X}
X
X/*
X * m a i n
X */
Xmain(argc, argv)
X  int  argc;
X  char *argv[];
X{
X  register INFO *info;
X  register int  i, j;
X  int           clear_event, unlock;
X  int           arg_count;
X  int           EvID;
X
X  clear_event = unlock = disp_all = disp_locks = FALSE;
X  arg_count = 0;
X
X  /*
X   * Parse command line arguments
X   */  
X  for (i = 1; i< argc; i++)
X    if (argv[i][0] == '-')
X      for (j = 1; j < strlen(argv[i]); j++)
X        switch(tolower(argv[i][j])) {
X          case '?':
X            usage();
X            exit(1);
X          case 'c':       /* clear event */
X            clear_event = TRUE;
X            break;
X          case 'a':
X            disp_all = TRUE;
X            break;
X          case 'l':
X            disp_locks = TRUE;
X            break;
X          case 'u':       /* unlock device */
X            unlock = TRUE;
X            break;
X          default:
X            usage();
X            exit(_errmsg(1, "unknown option '%c'\n", argv[i][j]));
X        }
X    else
X      arg_count++;
X
X  if ((info = link_info_mod()) == NULL)
X    exit(_errmsg(errno, "can't link to sysinfo data module\n"));
X
X  if (info->rev != REVISION) {
X    unlink_info_mod();
X    exit(_errmsg(1, "Revision mismatch, (mod = %d, getinfo = %d)\n",
X                 info->rev, REVISION));
X  }
X
X  if (clear_event) {    /* Reset the SYSINFO event */
X    if ((EvID = _ev_link(INFO_EVENT_NAME)) == -1) {
X      unlink_info_mod();
X      exit(_errmsg(errno, "can't link to event\n"));
X    }
X
X    if (_ev_set(EvID, 0, 0) == -1) {
X      unlink_info_mod();
X      exit(_errmsg(errno, "can't set event\n"));
X    }
X    _ev_unlink(EvID);
X  }
X  
X  if (unlock)     /* Unlock an entry */
X    for (i = 1; i < argc; i++)
X      if (argv[i][0] != '-')
X        if (info_lock(argv[i], 0) != -1)
X          info_unlock(argv[i], 0);
X        else
X          fprintf(stderr, "can't unlock %s\n", argv[i]);
X
X  if ((!clear_event && !unlock) || disp_locks || disp_all) {
X    printf("SYSINFO Rev. %d\n\n", info->rev);
X    printf("%-20.20s  %-10.10s  %-40.40s\n\n", "Name", "Type", "Parameter");
X    for (i = 0; i < info->num; i++)
X      display_info(&(info->entry[i]));      /* Display entries */
X  }
X
X  unlink_info_mod();
X}
X
X/*
X * d i s p l a y _ i n f o
X */
Xstatic void 
Xdisplay_info(entry)
X  register ENTRY *entry;
X{
X  register LOCK     *lock;
X  register procid   procdesc;
X  register mod_exec *modhdr;
X  register char     *mod_name;
X
X  if (disp_all || entry->type == T_LOCK) {  
X    printf("%-20.20s  %-10.10s  ", entry->name,
X           entry->type == T_UNKNOWN ? "*unknown*" :
X           entry->type == T_STRING ? "String" :
X           entry->type == T_NUM ? "Num" :
X           entry->type == T_LOCK ? "Lock" : "* ??? *");
X  }
X
X  switch (entry->type) {
X    case T_UNKNOWN:
X      break;
X
X    case T_STRING:
X      if (!disp_all)
X        break;
X      printf("%-40.40s", entry->data);
X      break;
X
X    case T_NUM:
X      if (!disp_all)
X        break;
X      printf("not supported yet");
X      break;
X
X    case T_LOCK:
X      lock = (LOCK *) entry->data;
X      if (lock->status == ST_FREE)
X        printf("not locked");
X      else {
X        if ((_get_process_desc(lock->pid, sizeof(procdesc),
X                                           &procdesc)) == -1 ||
X            lock->timbeg != procdesc._timbeg ||
X            lock->datbeg != procdesc._datbeg) 
X                                            /* Locking proc. still existing? */
X          printf("not locked, orphaned lock (process id %d)", lock->pid);
X        else {
X          mod_name = getmodname(procdesc._pmodul);
X          printf("locked by process %d (%s)", lock->pid, mod_name);
X        }
X      }
X      break;
X
X    default:
X      printf("possible damage of sysinfo data (invalid type)");
X  }
X
X  if (disp_all || entry->type == T_LOCK)  
X    printf("\n");
X}
X
X/*
X * u s a g e
X */
Xstatic void 
Xusage()
X{
X  fputs("Syntax: getinfo [<opts>] {<parm> [<opts>]}\n", stderr);
X  fputs("Function: display or modify sysinfo data\n", stderr);
X  fputs("Options:\n", stderr);
X  fputs("     -l   display locks (default)\n", stderr);
X  fputs("     -a   display not only locks\n", stderr);
X  fputs("     -c   clear sysinfo event\n", stderr);
X  fputs("     -u   unlock devices (given as parm)\n", stderr);
X}
END_OF_FILE
if test 6331 -ne `wc -c <'getinfo.c'`; then
    echo shar: \"'getinfo.c'\" unpacked with wrong size!
fi
# end of 'getinfo.c'
fi
if test -f 'man.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man.c'\"
else
echo shar: Extracting \"'man.c'\" \(6371 characters\)
sed "s/^X//" >'man.c' <<'END_OF_FILE'
X/************************************************************************
X *                                                                      *
X *   Copyrighted (C) 1987, 1988 by Ulrich Dessauer, Germering           *
X *                                                  (W-Germany)         *
X *                                                                      *
X *   This program can be copied and distributed freely for any          *
X *   non-commercial purposes. This program can only be incorporated     *
X *   into commercial software with the permission of the author.        *
X *                                                                      *
X *   If you should modify this program, the author would appreciate     *
X *   informations about the changes. Please send a (context) diff or    *
X *   the complete source to:                                            *
X *   address:     Ulrich Dessauer                                       *
X *                Kerschensteinerstr. 45                                *
X *                D-8034 Germering                                      *
X *                West Germany                                          *
X *                                                                      *
X *   e-mail:      ud@mutec.UUCP, ud@altger.UUCP                         *
X *                                                                      *
X *   Program:     man                                                   *
X *   Version:     0.98                                                  *
X *   Module:      man.c                                                 *
X *   Description: Prints an manual entry using the favorite pager       *
X *   Functions:   usage ()                                              *
X *                main (int, **char)                                    *
X *                manual (*char, **char)                                *
X *                                                                      *
X *   Auther(s):                                                         *
X *         Ulrich Dessauer    (ud)                                      *
X *                                                                      *
X *   Edition History                                                    *
X *    # | Date   | By  | Changes                                        *
X *   ===+========+=====+==============================================  *
X *    1 |03.10.88| ud  | Seperated includefiles for man and mwb         *
X *                                                                      *
X ************************************************************************/
X# ifndef LINT
Xstatic char *copyright = "Copyrighted (C) 1987, 1988 by Ulrich Dessauer, Germering, W-Germany";
X# endif LINT
X
X# include "man.h"
X# include <modes.h>
X# include <ctype.h>
X
Xextern void	exit ();
Xextern void	free ();
Xextern char	*fgets ();
Xextern char	*getenv ();
Xextern char	*info_str ();
Xextern char	*malloc ();
Xextern char	*strcat ();
Xextern char	*strcpy ();
Xextern FILE	*fopen ();
X
Xextern int	errno;
X
X# define 	MANEXT		".man"
X
Xchar		*mandir,*proff,*mindex,*pager;
X
Xchar		*help[] = {
X	"Syntax: man [<opts>]\n",
X	"Function: Prints a manual entry\n",
X	"Options:\n",
X	"     none.\n",
X	NULL
X};
X
X/*
X *	u s a g e
X */
Xusage ()
X{
X	int t;
X
X	for (t=0;help[t];++t)
X		(void) fputs(help[t],stderr);
X}
X
X/*
X *	m a i n
X */
Xmain (argc,argv,envp)
Xint argc;
Xchar *argv[];
Xchar *envp[];
X{
X	int		t;
X	int		noargs;
X	char		*x;
X	char 		s[256];
X	register char	*entry,*file;
X	char		lastfile[40];
X	FILE		*fp;
X	char		*mn;
X	
X	noargs = 1;
X	
X	/* Parse arguments */
X	for (t=1;t<argc;++t)
X		if (*argv[t] == '-') {
X			x = argv[t] + 1;
X			while (*x) {
X				switch (*x) {
X					case '?':
X					default:
X						usage ();
X						if (*x != '?')
X							(void) fprintf (stderr, "Unknown flag '%c'\n",*x);
X						exit (1);
X				}
X				if (*x) ++x;
X			}
X		} else
X			noargs = 0;
X	if (noargs) {
X		usage ();
X		exit(_errmsg(1, "No manual entry\n"));
X	}
X	
X	/* Get some sysinfo entries */
X	if (!(mn = malloc (80)))
X		exit (_errmsg (errno,"Out of memory\n"));
X	if (!(mandir = getenv ("MANDIR"))) {
X		if (!info_str ("mwb.mandir",mn,80))
X			mandir = MANDIR;
X		else {
X			mandir = mn;
X			if (!(mn = malloc (80)))
X				exit (_errmsg (errno,"Out of memory\n"));
X		}
X	}
X	if (!(proff = getenv ("PROFF"))) {
X		if (!info_str ("mwb.proff",mn,80))
X			proff = PROFF;
X		else {
X			proff = mn;
X			if (!(mn = malloc (80)))
X				exit (_errmsg (errno,"Out of memory!\n"));
X		}
X	}
X	if (!(mindex = getenv ("INDEX"))) {
X		if (!info_str ("mwb.index",mn,80))
X			mindex = INDEX;
X		else {
X			mindex = mn;
X			if (!(mn = malloc (80)))
X				exit (_errmsg (errno,"Out of memory\n"));
X		}
X	}
X	if (!(pager = getenv ("PAGER"))) {
X		if (!info_str ("mwb.pager",mn,80))
X			pager = PAGER;
X		else {
X			pager = mn;
X			if (!(mn = malloc (80)))
X				exit (_errmsg (errno,"Out of memory!\n"));
X		}
X	}
X	free (mn);
X	if (chdir (mandir) < 0)
X		exit (_errmsg (errno,"Can't change to '%s'!\n",mandir));
X	*lastfile = '\0';
X	fp = NULL;
X	for (t=1;t<argc;++t)
X		if (*argv[t] != '-') {
X			x = argv[t];
X			if (fp)
X				(void) fseek (fp, 0, 0);
X			else
X				if (!(fp = fopen (mindex,"r")))
X					exit (_errmsg (errno,"Can't open index file!\n"));
X			while (fgets (s,80,fp)) {
X				s[strlen (s) - 1] = '\0';
X				entry = s;
X				file = s;
X				while (*file && (!isspace (*file)))
X					++file;
X				if (*file) {
X					*file++ = '\0';
X					while (isspace (*file))
X						++file;
X				}
X				if (!*file) continue;
X				if ((!_cmpnam (entry,x,strlen (x))) && (strcmp (lastfile,file))) {
X					if (manual (file,envp))
X						break;
X					(void) strcpy (lastfile,file);
X				}
X			}
X		}
X	if (fp)
X		(void) fclose (fp);
X}
X
X/*
X *	m a n u a l
X */
Xmanual (x,en)
Xchar *x;
Xchar *en[];
X{
X	char	*args[6];
X	char	format[256];
X	int	pid, t, status;
X
X	(void) strcpy (format,x);
X	(void) strcat (format,MANEXT);
X	if (access (format,S_IREAD)) {
X		if (access (x,S_IREAD)) {
X			printf ("Entry %s not found\n",x);
X			return (0);
X		}
X		args[0] = "shell";
X		args[1] = proff;
X		args[2] = x;
X		args[3] = "!";
X		args[4] = pager;
X		args[5] = NULL;
X	} else {
X		args[0] = pager;
X		args[1] = format;
X		args[2] = NULL;
X	}
X	if ((pid = os9exec (os9forkc,args[0],args,en,0,0,3)) < 0)
X		exit (_errmsg (errno,"Can't fork '%s'\n", args[1]));
X	status = 0;
X	while (((t = wait (&status)) != pid) && (t != -1))
X		;
X	if ((t == pid) && status)
X		return (1);
X	else
X		return (0);
X}
END_OF_FILE
if test 6371 -ne `wc -c <'man.c'`; then
    echo shar: \"'man.c'\" unpacked with wrong size!
fi
# end of 'man.c'
fi
if test -f 'pw.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pw.c'\"
else
echo shar: Extracting \"'pw.c'\" \(6614 characters\)
sed "s/^X//" >'pw.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib:  password routines
X |
X |
X |     Copyright (c) 1988 by Wolfgang Ocker, Puchheim,
X |                           Ulli Dessauer, Germering and
X |                           Reimer Mellin, Muenchen
X |                           (W-Germany)
X |
X |  This  programm can  be  copied and  distributed freely  for any
X |  non-commercial  purposes.   It can only  be  incorporated  into
X |  commercial software with the written permission of the authors.
X |
X |  If you should modify this program, the authors would appreciate
X |  a notice about the changes. Please send a (context) diff or the
X |  complete source to:
X |
X |  address:     Wolfgang Ocker
X |               Lochhauserstrasse 35a
X |               D-8039 Puchheim
X |               West Germany
X |
X |  e-mail:      weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP
X |               pyramid!tmpmbx!recco!weo
X |               pyramid!tmpmbx!nitmar!ud
X |               pyramid!tmpmbx!ramsys!ram
X |
X * ----------------------------------------------------------------- */
X
X#define PATCHLEVEL 1
X
X#include <stdio.h>
X#include <ctype.h>
X#include <pwd.h>
X#include <sgstat.h>
X
Xstatic char           EMPTY[] = "";
Xstatic FILE           *pwf = NULL;
Xstatic char           line[BUFSIZ+1];
Xstatic struct passwd  passwd;
X
X#define TRUE  (-1)
X#define FALSE (0)
X
Xextern FILE *ddfopen();
X
Xint _pw_secure = 0;
X
X/*
X * s e t p w e n t
X */
Xint setpwent()
X{
X  char fn[100];
X
X  if (!pwf) {
X    if ((pwf = ddfopen(PASSWD, fn, "r", _pw_secure)) == NULL)
X      return(-1);
X  }
X  else
X    rewind(pwf);
X
X  return(0);    /* OK */
X}
X
X/*
X *  e n d p w e n t
X */
Xvoid endpwent()
X{
X  if (pwf) {
X    fclose (pwf);
X    pwf = NULL;
X  }
X}
X
X/*
X * p w s k i p
X */
Xstatic char *pwskip(p)
X  register char *p;
X
X{
X  while (*p && *p != ',' && *p != '\n')
X    ++p;
X
X  if (*p)
X    *p++ = 0;
X
X  return(p);
X}
X
X/*
X * _ g e t p w
X */
Xstruct passwd *_getpw(pwd, pwline)
X  register struct passwd *pwd;
X  char                   *pwline;
X{
X  register char *p;
X  char          *cp;
X  static char   tmp[BUFSIZ+1];
X  static char   comment[81];
X  static char   gecos[81];
X  
X  strcpy(tmp, pwline);
X
X  p = tmp;
X  pwd->pw_name = p;
X
X  p = pwskip(p);
X  pwd->pw_passwd = p;
X
X  p = pwskip(p);
X  cp = p;
X  while (*cp && (*cp != '.'))
X    ++cp;
X
X  if (*cp)
X    *cp++ = '\0';
X 
X  pwd->pw_gid = atoi(p);
X
X  p = cp;
X  p = pwskip(p);
X  pwd->pw_uid = atoi(cp);
X
X  cp = p;
X
X  p = pwskip(p);
X  pwd->pw_prio = atoi(cp);
X
X  pwd->pw_comment = EMPTY;
X  pwd->pw_gecos   = EMPTY;
X  pwd->pw_age     = EMPTY;
X  pwd->pw_xdir    = p;
X
X  p = pwskip(p);
X  pwd->pw_dir = p;
X
X  p = pwskip(p);
X  pwd->pw_shell = p;
X
X  p = pwskip(p);
X  pwd->pw_junk = p;
X
X  p = pwskip(p);
X
X  getpwopt(pwd->pw_junk, comment, PW_COMMENT, sizeof(comment));
X  pwd->pw_comment = comment;
X  getpwopt(pwd->pw_junk, gecos, PW_GECOS, sizeof(gecos));
X  pwd->pw_gecos = gecos;
X  return(pwd);
X}
X
X/*
X * g e t p w e n t
X */
Xstruct passwd *getpwent()
X{
X  if (!pwf)
X    if (setpwent() < 0)
X      return(NULL);
X
X  do {
X    if (!fgets(line, BUFSIZ, pwf))
X      return(NULL);
X  } while (line[0] == '#' || line[0] == '*');
X
X  if (!_getpw(&passwd,  line))
X    return(NULL);
X
X  return(&passwd);
X}
X
X/*
X * g e t p w u i d
X */
Xstruct passwd *getpwuid(uid)
X  int uid;
X
X{
X  int found = 0;
X	
X  if (setpwent() < 0)
X    return(NULL);
X
X  while ((!found) && fgets(line, BUFSIZ, pwf)) {
X    if (line[0] == '#' || line[0] == '*')
X      continue;
X
X    if (_getpw(&passwd, line))
X      found = (passwd.pw_uid == uid);
X  }
X
X  if (found)
X    return(&passwd);
X  else
X    return(NULL);
X}
X
X/*
X * _ s t r c m p
X */
Xint _strccmp(a, b)
X  register char *a,*b;
X
X{
X  register int equal = TRUE;
X
X  while (equal && *a && *b)
X    equal = (tolower(*a++) == tolower(*b++));
X
X  if (equal)
X    return (*b - *a);
X  return(TRUE);       /* nicht gleich! */
X}
X
X/*
X * g e t p w n a m
X */
Xstruct passwd *getpwnam(name)
X  char *name;
X{
X  int found = 0;
X	
X  if (setpwent() < 0)
X    return(NULL);
X
X  while ((!found) && fgets(line, BUFSIZ, pwf)) {
X    if (line[0] == '#' || line[0] == '*')
X      continue;
X    if (_getpw(&passwd, line)) 
X      found = !_strccmp(passwd.pw_name, name);
X  }
X
X  if (found)
X    return(&passwd);
X  else
X    return(NULL);
X}
X
X/*
X * f g e t p w e n t
X */
Xstruct passwd *fgetpwent (f)
X  FILE *f;
X
X{
X  struct passwd *pw = NULL;
X	
X  do {
X    if (fgets (line, BUFSIZ, f))
X      pw = _getpw(line, &passwd);
X    else
X      pw = NULL;
X  } while (pw && (line[0] == '#' || line[0] == '*'));
X
X  return(pw);
X}
X
X/*
X * g e t p w
X */
Xint getpw(uid, name)
X{
X  struct passwd *pw;
X
X  if ((pw = getpwuid(uid)) == NULL)
X    return(-1);
X
X  strcpy(name, pw->pw_name);
X  return(0);
X}
X
X/*
X * _ c m p u i d
X */
Xint _cmpuid(uidstr, uid)
X  char  *uidstr;
X  int   *uid;
X{
X  int i;
X
X  i = 0;
X  while (*uidstr && *uidstr != '.')
X    if (isdigit(*uidstr))
X      i = i * 10 + *uidstr++ - '0';
X    else
X      return(-1);
X  
X  if (!*uidstr++) {
X    *uid = i;
X    return(0);
X  }
X
X  *uid = i << 16;
X
X    
X  i = 0;
X  while (*uidstr && *uidstr != '.')
X    if (isdigit(*uidstr))
X      i = i * 10 + *uidstr++ - '0';
X    else
X      return(-1);
X  
X  *uid |= i;
X  
X  if (*uidstr)
X    return(0);
X  return(-1);
X}
X
X
X/*
X * o p t s k i p
X */
Xstatic char *optskip(s)
X  register char *s;
X{
X  while (*s && *s != '|')
X    s++;
X  
X  if (*s)
X    s++;
X  return(s);
X}
X
X
X/*
X * g e t p w o p t
X */
Xint getpwopt(junk, buf, opt, max)
X  register char *junk;
X  char          *buf;
X  register char opt;
X  register int  max;
X{
X  register char *cp;
X  int           res;
X
X  res = -1;
X  --max;
X  buf[0] = '\0';
X  
X  while (*junk != '\0' && res)
X    if (*junk != '-' || *(junk+1) != opt)
X      junk = optskip(junk);
X    else {
X      cp   = buf;
X      junk += *(junk+2) == '=' ? 3 : 2;
X
X      while (*junk != '\0' && *junk != '|' && --max > 0)
X        *cp++ = *junk++;
X
X      *cp = '\0';
X      res = 0;
X      break;
X    }
X  
X  return(res);
X}
X
X/*
X * g e c o s s k i p
X */
Xstatic char *gecosskip(s)
X  register char *s;
X{
X  while (*s && *s != ':')
X    s++;
X
X  if (*s != '\0')
X    *s++ = '\0';
X
X  return(*s == '\0' ? NULL : s);
X}
X
X/*
X * g e t g e c o s
X */
Xstruct gecos *getgecos(gecos_field)
X  register char *gecos_field;
X{
X  static struct gecos gecos;
X  
X  if (gecos_field == NULL || gecos_field[0] == '\0')
X    return(NULL);
X
X  gecos.fullname     = gecos.organization =
X  gecos.office_phone = gecos.home_phone   = NULL;
X
X  gecos.fullname = gecos_field;
X
X  if ((gecos.organization = gecosskip(gecos.fullname)) == NULL)
X    return(&gecos);
X
X  if ((gecos.office_phone = gecosskip(gecos.organization)) == NULL)
X    return(&gecos);
X
X  gecos.home_phone = gecosskip(gecos.office_phone);
X  return(&gecos);
X}
END_OF_FILE
if test 6614 -ne `wc -c <'pw.c'`; then
    echo shar: \"'pw.c'\" unpacked with wrong size!
fi
# end of 'pw.c'
fi
if test -f 'utmp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'utmp.c'\"
else
echo shar: Extracting \"'utmp.c'\" \(6893 characters\)
sed "s/^X//" >'utmp.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib:  utmp and wtmp routines
X |
X |
X |     Copyright (c) 1988 by Wolfgang Ocker, Puchheim,
X |                           Ulli Dessauer, Germering and
X |                           Reimer Mellin, Muenchen
X |                           (W-Germany)
X |
X |  This  programm can  be  copied and  distributed freely  for any
X |  non-commercial  purposes.   It can only  be  incorporated  into
X |  commercial software with the written permission of the authors.
X |
X |  If you should modify this program, the authors would appreciate
X |  a notice about the changes. Please send a (context) diff or the
X |  complete source to:
X |
X |  address:     Wolfgang Ocker
X |               Lochhauserstrasse 35a
X |               D-8039 Puchheim
X |               West Germany
X |
X |  e-mail:      weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP
X |               pyramid!tmpmbx!recco!weo
X |               pyramid!tmpmbx!nitmar!ud
X |               pyramid!tmpmbx!ramsys!ram
X |
X * ----------------------------------------------------------------- */
X
X#define PATCHLEVEL 1
X
X#include <stdio.h>
X#include <time.h>
X#include <utmp.h>
X#include <strings.h>
X#include <ctype.h>
X#include <sgstat.h>
X
Xstatic struct utmp ut;
Xstatic FILE        *_fpw = NULL;
Xstatic char        *utmp_file = UTMP_FILE;
X
X#define PID  1
X#define LINE 2
X
X#define TRUE  1
X#define FALSE 0
X
Xextern char *gethostname();
X
X/*
X * _ i n s e r t
X */
Xstatic int _insert(utmp, stat, flag)
X  register struct utmp *utmp;
X  char                 *stat;
X  int                  flag;
X{
X  register FILE *fp;
X  register int  pos;
X  int           itmp;
X  int           new, ok;
X  struct utmp   u;
X  int           first;
X  char          line[33];
X  register char *status, *cp;
X	
X  pos = first = 0;
X
X  if ((fp = fopen(utmp_file, "r+")) == NULL)
X    if ((fp = fopen(utmp_file, "w")) == NULL)
X      return(-1);
X    else
X      first = TRUE;
X  else {
X    new = ok = FALSE;
X
X    if (flag != LINE) {
X      _gs_devn(0, line+1);
X      line[0] = '/';
X    }
X    else
X      strcpy(line, utmp->ut_line);
X
X    while (!new && !(new = !fread(&u, sizeof(struct utmp), 1, fp)))
X      switch (flag) {
X        case NULL:
X          if (u.ut_type == EMPTY)
X            new = 1;
X          else
X            pos += sizeof(struct utmp);
X          break;
X
X        case PID:
X          if (u.ut_pid == utmp->ut_pid)
X            new = ok = 1;
X          else
X            pos += sizeof(struct utmp);
X          break;
X
X        case LINE:
X        default:
X          if (!strcmp(u.ut_line, line)) 
X            new = ok = 1;
X          else
X            pos += sizeof(struct utmp);
X          break;
X      }
X
X    fseek(fp, pos, 0);
X  }
X
X  if (stat) {
X    if (!ok) {
X      fclose(fp);
X      return(-1);
X    }
X
X    status = u.ut_status;
X    while (*stat) {
X      if (cp = index(status, tolower(*stat)))
X        *cp = *stat;
X      else 
X        if (cp = index(status, toupper(*stat)))
X          *cp = *stat;
X        else 
X          if (strlen(status) < 9) {
X            itmp = strlen(status);
X            status[itmp]   = *stat;
X            status[itmp+1] = '\0';
X          }
X      ++stat;
X    }
X    fwrite (&u, sizeof(struct utmp), 1, fp);
X  }
X  else
X    fwrite(utmp, sizeof(struct utmp), 1, fp);
X
X  fclose(fp);
X  if (first)
X    chmod(utmp_file, 013);
X  return(0);
X}
X
X/*
X * _ c l e a r
X */
Xstatic _clear(utmp)
X  register struct utmp *utmp;
X{
X  struct        utmp u;
X  register FILE *fp;
X  register int  pos;
X  register int  ok, found;
X	
X  ok = found = FALSE;
X  endwhoent();
X
X  if (!(fp = fopen(utmp_file, "r+")))
X    return(-1);
X
X  pos = 0;
X  while (!ok && !(ok = !fread(&u, sizeof(struct utmp), 1, fp)))
X    if (u.ut_type == USER_PROCESS && u.ut_pid == utmp->ut_pid)
X      ok = found = TRUE;
X    else
X      pos += sizeof(struct utmp);
X
X  if (!found) {
X    fclose(fp);
X    return(-1);
X  }
X
X  fseek(fp, pos, 0);
X  u.ut_type = EMPTY;
X  fwrite(&u, sizeof(struct utmp), 1, fp);
X  fclose(fp);
X  return(0);
X}
X
X/*
X * _ u t m p _ s t a t
X */
X_utmp_stat(stat)
X  register char *stat;
X{
X  if (stat)
X    return(_insert(&ut, stat, LINE+1));
X  else
X    return(-1);
X}
X
X/*
X * _ u t m p _ w r i t e
X */
X_utmp_write(type, name, line, pid, status, uid, gid)
X  register      int type;
X  register char *name, *line;
X  int           pid;
X  register char *status;
X  int           uid, gid;
X{
X  char          hostname[20];
X  register char *cp;
X  struct sgbuf  buf;
X	
X  if (type == BOOT_TIME) {
X    if ((cp = gethostname(hostname, sizeof(hostname))) != NULL)
X      strcpy(ut.ut_user, cp);
X    else
X      strcpy(ut.ut_user, BOOT_MSG);
X
X    strcpy(ut.ut_line, ".");
X    ut.ut_pid     = 0;
X    ut.ut_type    = type;
X    strcpy(ut.ut_id, "999");
X    ut.ut_uid     = ut.ut_gid = 0;
X    ut.ut_baud    = -1;
X    *ut.ut_status = '\0';
X  }
X  else {
X    strcpy(ut.ut_user, name);
X    strcpy(ut.ut_line, line);
X    ut.ut_pid  = pid;
X    ut.ut_type = type;
X    cp = line;
X    while (*cp && !isdigit(*cp))
X      ++cp;
X
X    if (*cp == '\0') {
X      cp = "0";
X      ut.ut_baud = -1;
X    }
X    else {
X      _gs_opt(0, &buf);
X      ut.ut_baud = buf.sg_baud;
X    }
X
X    if (type == USER_PROCESS) {
X      ut.ut_uid = uid;
X      ut.ut_gid = gid;
X    }
X    else
X      ut.ut_uid = ut.ut_gid = 0;
X
X    strncpy(ut.ut_id, cp, 3);
X    strncpy(ut.ut_status, status, 9);
X  }
X
X  time(&ut.ut_time);
X
X  if (type == EMPTY)
X    return(_clear(&ut));
X  else
X    if (*ut.ut_line)
X      return(_insert(&ut, NULL, LINE));
X    else
X      return(_insert(&ut, NULL, NULL));
X}
X
X/*
X * s e t w h o e n t
X */
Xsetwhoent()
X{
X  if (_fpw == NULL) {
X    if (!(_fpw = fopen(utmp_file, "r")))
X      return(-1);
X    else
X      return(0);
X  } 
X  else 
X    return(fseek(_fpw, 0, 0));
X}
X
X/*
X * g e t w h o e n t
X */
Xstruct utmp *getwhoent()
X{
X  if (_fpw == NULL)
X    if (setwhoent())
X      return(NULL);
X
X  if (!fread(&ut, sizeof(struct utmp), 1, _fpw))
X    return(NULL);
X  return(&ut);
X}
X
X/*
X * e n d w h o e n t
X */
Xint endwhoent()
X{
X  if (_fpw)
X    fclose(_fpw);
X  _fpw = NULL;
X  return(0);
X}
X
X/*
X * g e t u t e n t
X */
Xstruct utmp *getutent()
X{
X  return(getwhoent());
X}
X
X/*
X * s e t u t e n t
X */
Xsetutent()
X{
X  return(setwhoent());
X}
X
X/*
X * e n d u t e n t
X */
Xint endutent()
X{
X  return(endwhoent());
X}
X
X/*
X * g e t u t i d
X */
Xstruct utmp *getutid(id)
X  register struct utmp *id;
X{
X  register struct utmp *utmp;
X	
X  setutent();
X  while (utmp = getutent()) 
X    if (utmp->ut_type == id->ut_type)
X      break;
X
X   return(utmp);
X}
X
X/*
X * g e t u t l i n e
X */
Xstruct utmp *getutline(line)
X  register struct utmp *line;
X{
X  register struct utmp *utmp;
X	
X  while (utmp = getutent())
X    if (!strcmp(utmp->ut_line, line->ut_line))
X      break;
X
X  return(utmp);
X}
X
X/*
X * p u t u t l i n e
X */
Xpututline(utmp)
X  register struct utmp *utmp;
X{
X  return(_insert(utmp, NULL, LINE));
X}
X
X/*
X * u t m p n a m e
X */
Xint utmpname (file)
X  register char *file;
X{
X  utmp_file = file;
X
X  if (_fpw)
X    fclose (_fpw);
X  return(0);
X}
X
END_OF_FILE
if test 6893 -ne `wc -c <'utmp.c'`; then
    echo shar: \"'utmp.c'\" unpacked with wrong size!
fi
# end of 'utmp.c'
fi
if test -f 'perror.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'perror.c'\"
else
echo shar: Extracting \"'perror.c'\" \(7455 characters\)
sed "s/^X//" >'perror.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib:  perror(), sys_errlist
X |
X |
X |     Copyright (c) 1988 by Wolfgang Ocker, Puchheim,
X |                           Ulli Dessauer, Germering and
X |                           Reimer Mellin, Muenchen
X |                           (W-Germany)
X |
X |  This  programm can  be  copied and  distributed freely  for any
X |  non-commercial  purposes.   It can only  be  incorporated  into
X |  commercial software with the written permission of the authors.
X |
X |  If you should modify this program, the authors would appreciate
X |  a notice about the changes. Please send a (context) diff or the
X |  complete source to:
X |
X |  address:     Wolfgang Ocker
X |               Lochhauserstrasse 35a
X |               D-8039 Puchheim
X |               West Germany
X |
X |  e-mail:      weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP
X |               pyramid!tmpmbx!recco!weo
X |               pyramid!tmpmbx!nitmar!ud
X |               pyramid!tmpmbx!ramsys!ram
X |
X * ----------------------------------------------------------------- */
X
X#define PATCHLEVEL 1
X
X/*
X * perror(s): print an error message
X */
X
X#ifdef LINT
X#define remote
X#endif
X
X#include <stdio.h>
X
Xextern int errno;
X
Xremote char *sys_errlist[] = {
X  "",
X  "000:001 aborted with an error",
X  "000:002 keyboard quit",
X  "000:003 keyboard interrupt",
X  "000:004 ",
X  "000:005 ",
X  "000:006 ",
X  "000:007 ",
X  "000:008 ",
X  "000:009 ",
X  "000:010 ",
X  "000:011 ",
X  "000:012 ",
X  "000:013 ",
X  "000:014 ",
X  "000:015 ",
X  "000:016 ",
X  "000:017 ",
X  "000:018 ",
X  "000:019 ",
X  "000:020 ",
X  "000:021 ",
X  "000:022 ",
X  "000:023 ",
X  "000:024 ",
X  "000:025 ",
X  "000:026 ",
X  "000:027 ",
X  "000:028 ",
X  "000:029 ",
X  "000:030 ",
X  "000:031 ",
X  "000:032 ",
X  "000:033 ",
X  "000:034 ",
X  "000:035 ",
X  "000:036 ",
X  "000:037 ",
X  "000:038 ",
X  "000:039 ",
X  "000:040 ",
X  "000:041 ",
X  "000:042 ",
X  "000:043 ",
X  "000:044 ",
X  "000:045 ",
X  "000:046 ",
X  "000:047 ",
X  "000:048 ",
X  "000:049 ",
X  "000:050 ",
X  "000:051 ",
X  "000:052 ",
X  "000:053 ",
X  "000:054 ",
X  "000:055 ",
X  "000:056 ",
X  "000:057 ",
X  "000:058 ",
X  "000:059 ",
X  "000:060 ",
X  "000:061 ",
X  "000:062 ",
X  "000:063 ",
X  "000:064 illegal function code (math)",
X  "000:065 ascii->numeric format conversion error (math)",
X  "000:066 not a number (math)",
X  "000:067 illegal argument (usually math)",
X  "000:068 ",
X  "000:069 ",
X  "000:070 ",
X  "000:071 ",
X  "000:072 ",
X  "000:073 ",
X  "000:074 ",
X  "000:075 ",
X  "000:076 ",
X  "000:077 ",
X  "000:078 ",
X  "000:079 ",
X  "000:080 ",
X  "000:081 ",
X  "000:082 ",
X  "000:083 ",
X  "000:084 ",
X  "000:085 ",
X  "000:086 ",
X  "000:087 ",
X  "000:088 ",
X  "000:089 ",
X  "000:090 ",
X  "000:091 ",
X  "000:092 ",
X  "000:093 ",
X  "000:094 ",
X  "000:095 ",
X  "000:096 ",
X  "000:097 ",
X  "000:098 ",
X  "000:099 ",
X  "000:100 ",
X  "000:101 ",
X  "000:102 bus trap",
X  "000:103 address trap",
X  "000:104 illegal instruction",
X  "000:105 divide by zero",
X  "000:106 \"chk\" instruction trap",
X  "000:107 \"trapv\" instruction trap",
X  "000:108 privileged instruction",
X  "000:109 trace exception",
X  "000:110 illegal instruction (1010)",
X  "000:111 illegal instruction (1111)",
X  "000:112 exception 12",
X  "000:113 coprocessor protocol violation",
X  "000:114 system stack frame format error",
X  "000:115 uninitialized interrupt",
X  "000:116 exception 16",
X  "000:117 exception 17",
X  "000:118 exception 18",
X  "000:119 exception 19",
X  "000:120 exception 20",
X  "000:121 exception 21",
X  "000:122 exception 22",
X  "000:123 exception 23",
X  "000:124 spurious interrupt",
X  "000:125 ",
X  "000:126 ",
X  "000:127 ",
X  "000:128 ",
X  "000:129 ",
X  "000:130 ",
X  "000:131 ",
X  "000:132 ",
X  "000:133 an uninitialized user TRAP (1-15) was executed",
X  "000:134 ",
X  "000:135 ",
X  "000:136 ",
X  "000:137 ",
X  "000:138 ",
X  "000:139 ",
X  "000:140 ",
X  "000:141 ",
X  "000:142 ",
X  "000:143 ",
X  "000:144 ",
X  "000:145 ",
X  "000:146 ",
X  "000:147 ",
X  "000:148 fpcp unordered condition",
X  "000:149 fpcp inexact result",
X  "000:150 fpcp divide by zero",
X  "000:151 fpcp underflow",
X  "000:152 fpcp operand error",
X  "000:153 fpcp overflow",
X  "000:154 fpcp not a number",
X  "000:155 exception 55",
X  "000:156 pmmu configuration",
X  "000:157 pmmu illegal operation",
X  "000:158 pmmu access level violation",
X  "000:159 exception 59",
X  "000:160 exception 60",
X  "000:161 exception 61",
X  "000:162 exception 62",
X  "000:163 exception 63",
X  "000:164 no permission",
X  "000:165 arguments to F$ChkNam didn't match",
X  "000:166 system stack overflow",
X  "000:167 invalid event ID number",
X  "000:168 event not found",
X  "000:169 the event is busy",
X  "000:170 impossible event parameters",
X  "000:171 system data structures have been damaged",
X  "000:172 module revision is incompatable with operating system",
X  "000:173 path became lost because network node was down",
X  "000:174 bad disk partition, or no active partition",
X  "000:175 ",
X  "000:176 ",
X  "000:177 ",
X  "000:178 ",
X  "000:179 ",
X  "000:180 ",
X  "000:181 ",
X  "000:182 ",
X  "000:183 ",
X  "000:184 ",
X  "000:185 ",
X  "000:186 ",
X  "000:187 ",
X  "000:188 ",
X  "000:189 ",
X  "000:190 ",
X  "000:191 ",
X  "000:192 ",
X  "000:193 ",
X  "000:194 ",
X  "000:195 ",
X  "000:196 ",
X  "000:197 ",
X  "000:198 ",
X  "000:189 ",
X  "000:200 the path table is full",
X  "000:201 bad path number",
X  "000:202 system IRQ table is full",
X  "000:203 bad I/O mode",
X  "000:204 system device table is full",
X  "000:205 bad module header",
X  "000:206 system module directory is full",
X  "000:207 memory full",
X  "000:208 unknown service code ",
X  "000:209 non-sharable module is busy",
X  "000:210 bad page address",
X  "000:211 end of file",
X  "000:212 IRQ vector is busy",
X  "000:213 non-existing segment",
X  "000:214 file not accessible",
X  "000:215 bad pathlist",
X  "000:216 file not found",
X  "000:217 file segment list is full",
X  "000:218 creating an existing file",
X  "000:219 illegal memory block address",
X  "000:220 modem data carrier lost",
X  "000:221 module not found",
X  "000:222 system clock not running",
X  "000:223 deleting stack memory",
X  "000:224 illegal process ID",
X  "000:225 bad IRQ parameter",
X  "000:226 no children",
X  "000:227 invalid trap number",
X  "000:228 process has aborted",
X  "000:229 system process table is full",
X  "000:230 illegal fork parameter",
X  "000:231 known module",
X  "000:232 bad module CRC",
X  "000:233 unprocessed signal pending",
X  "000:234 non executable module",
X  "000:235 bad name",
X  "000:236 bad module header parity",
X  "000:237 no RAM available",
X  "000:238 directory is not empty",
X  "000:239 no available task number",
X  "000:240 illegal unit (drive) number",
X  "000:241 bad sector number",
X  "000:242 media is write protected",
X  "000:243 I/O error - bad check sum",
X  "000:244 read error",
X  "000:245 write error",
X  "000:246 device not ready",
X  "000:247 seek error",
X  "000:248 media full",
X  "000:249 incompatable media",
X  "000:250 device busy",
X  "000:251 disk media has changed",
X  "000:252 record is busy",
X  "000:253 non-sharable file/device is busy",
X  "000:254 I/O deadlock error",
X  "000:255 device is format protected" };
X
Xint sys_nerr = 256;
X
Xint perror(s)
X
X  char *s;
X
X{
X  fprintf(stderr, "%s: %s\n", _prgname(), s);
X  if (errno > sys_nerr)   /* zu grosse Fehlernummer? */
X    fprintf(stderr, "%03d.%03d \n", errno >> 8, errno & 0xFF);
X  else {
X    fputs(sys_errlist[errno], stderr);
X    fputs("\n", stderr);
X  }
X  
X  return(errno);
X}
END_OF_FILE
if test 7455 -ne `wc -c <'perror.c'`; then
    echo shar: \"'perror.c'\" unpacked with wrong size!
fi
# end of 'perror.c'
fi
if test -f 'setup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'setup.c'\"
else
echo shar: Extracting \"'setup.c'\" \(8038 characters\)
sed "s/^X//" >'setup.c' <<'END_OF_FILE'
X/*
X *                          SETUP for SYSINFO
X *
X *  Copyrights (c) 1988 by reccoware systems, Wolfgang Ocker, Puchheim
X *
X *
X *
X *                           IMPORTANT NOTICE
X * =====================================================================
X *
X * I  would  like to  establish the SYSINFO  concept as a  STANDARD  for
X * OS-9/68000.  So  please  DON'T CHANGE  ANYTHING.  Please send any bug
X * reports or suggestions to
X *
X *
X *            Wolfgang Ocker
X *            Lochhauserstrasse 35a
X *            D-8039 Puchheim
X *            Tel. +49 89 / 80 77 02
X *
X *            e-mail: weo@recco    (...!pyramid!tmpmbx!recco!weo)
X *                    weo@altger   (...!altnet!altger!weo)
X *                    ocker@lan.informatik.tu-muenchen.dbp.de
X *
X *
X * I will maintain the  SYSINFO package and keep it (upward) compatible!
X * You may not distribute any modified  versions, or programs which rely 
X * on a modified version.
X *
X *              If you don't like SYSINFO, don't use it!
X */
X
X/*
X * Revision history
X *
X *  #    Date     Comments                                              By
X * -------------------------------------------------------------------- ---
X * 00  09/16/88   Prepared for net release                              weo
X * 01  10/07/88   After "linting" corrected some errors ...             weo
X *
X */
X
X#define PATCHLEVEL 1
X
X#include <stdio.h>
X#include <strings.h>
X#include <module.h>
X#include <ctype.h>
X
X#include "infomod.h"
X
Xextern int errno;
X
Xint debug;
X
X#define DEBUG(l,s,v) if (debug>=l) (void) fprintf(stderr, s, v);
X
Xstatic char *Copyright = "Copyrights (c) 1988 by reccoware systems puchheim";
X
Xvoid usage();
X
X/*
X * g e t _ l i n e
X *
X * "Parse" a line of the SYSINFO file
X */
Xstatic int
Xget_line(buf, name, type, len, data)
X  register char *buf;     /* Zeile */
X  char          *name;    /* Name, der gefunden wurde */
X  char          *type;    /* Type (s/d/l) */
X  int           *len;     /* Laenge */
X  char          *data;    /* Daten */
X{
X  register char *cp;
X
X  /*
X   * A line of the SYSINFO file looks like
X   * <name>,<type>[=[<data>|<length>]
X   *
X   * <data> is ignored on lock entries and should be omitted
X   */
X  if ((cp = index(buf, ',')) == NULL)
X    return(FAILED);
X  
X  *cp++ = '\0';
X  (void) strcpy(name, buf);  /* Name of the entry */
X
X  /*
X   * Need a '=' if not a lock entry
X   */
X  if (*cp != 'l' && *(cp+1) != '=')
X    return(FAILED);
X
X  *type = *cp;
X  buf   = cp+2;
X
X  switch (*type) {
X    case 's':       /* String */
X      (void) strcpy(data, buf);
X      *len = strlen(data) + 1;
X      break;
X
X    case 'l':       /* Lock */
X      *len = sizeof(LOCK);
X      break;
X
X    case 'd':       /* Data */
X      *len = atoi(buf);
X      break;
X
X    case 'n':           /* Number, not supported */
X      return(FAILED);
X
X    default:
X      return(FAILED);
X  }
X
X  *len = ((*len + 1) >> 1) << 1;    /* Word alignment */
X
X  return(OK);
X}
X
X/*
X * i n f o _ s e t u p
X * 
X * Read SYSINFO file and setup SYSINFO data module
X */
Xint 
Xinfo_setup(info_fp)
X  FILE *info_fp;
X{
X  char     buf[200];
X  char     name[200], data[200];
X  char     type;
X  int      len;
X  char     *data_ptr;
X  char     *cp;
X  mod_exec *info_module;
X  int      info_event;
X  int      info_size, info_num;
X  INFO     *info;
X  int      i, j;
X
X  info_size = info_num  = 0;
X
X  /*
X   * 1st pass: determine required size of data module
X   */
X  while (fgets(buf, sizeof(buf), info_fp)) {
X    /*
X     * Ignore comments
X     */
X    if (buf[0] == '*' || buf[0] == '#')
X      continue;
X    if (cp = index(buf, '\n'))
X      *cp = '\0';
X    
X    DEBUG(2, "Line = '%s'\n", buf);
X
X    if (get_line(buf, name, &type, &len, data) == FAILED)
X      continue;     /* Ignore incorrect lines */
X
X    DEBUG(2, "name = '%s', ", name);
X    DEBUG(2, "type = '%c', ", type);
X    DEBUG(2, "len  = %d", len);
X    if (type == 's') {
X      DEBUG(2, ", data = '%s'\n", data);
X    }
X    else {
X      DEBUG(2, "\n", 0);
X    }
X
X    info_size += (((strlen(name)+2)>>1)<<1) + len;    /* Alignment */
X    info_num++;
X  }
X
X  info_size += sizeof(INFO) + (info_num-1)*sizeof(ENTRY);
X
X  /*
X   * Create the data module
X   */
X  if ((info_module = (mod_exec *) _mkdata_module(INFO_MODULE_NAME,
X                     info_size, 0x8001, 0x0333)) == (mod_exec *) -1)
X    return(FAILED);
X
X  info = (INFO *) (((char *) info_module) + info_module->_mexec);
X  info->num = info_num;
X  info->rev = REVISION;   /* Revision number */
X
X  data_ptr = ((char *) info) + (info_num-1) * sizeof(ENTRY) + sizeof(INFO);
X
X  DEBUG(1, "info_num  = %d\n", info_num);
X  DEBUG(1, "info_size = %d\n", info_size);
X  DEBUG(1, "info      = %x\n", info);
X  DEBUG(1, "data_ptr  = %x\n", data_ptr);
X
X  /*
X   * 2nd pass: fill the data module
X   */
X  (void) fseek(info_fp, 0, 0);     /* Rewind */
X
X  i = 0;
X
X  while (fgets(buf, sizeof(buf), info_fp)) {
X    /*
X     * Ignore comments
X     */
X    if (buf[0] == '*' || buf[0] == '#')
X      continue;
X    if (cp = index(buf, '\n'))
X      *cp = '\0';
X
X    DEBUG(1, "Line = '%s'\n", buf);
X
X    if (get_line(buf, name, &type, &len, data) == FAILED)
X      continue;
X
X    DEBUG(1, "name = '%s', ", name);
X    DEBUG(1, "type = '%c', ", type);
X    DEBUG(1, "len  = %d", len);
X    if (type == 's') {
X      DEBUG(1, ", data = '%s'\n", data);
X    }
X    else {
X      DEBUG(1, "\n", 0);
X    }
X  
X    info->entry[i].type = type == 's' ? T_STRING : 
X                          type == 'n' ? T_NUM :
X                          type == 'd' ? T_DATA :
X                          type == 'l' ? T_LOCK : T_UNKNOWN;
X
X    info->entry[i].name  = data_ptr;
X
X    /*
X     * Remove leading slash of lock entry names
X     */
X    if (type == 'l' && name[0] == '/')
X      (void) strcpy(name, name+1);
X
X    (void) strcpy(data_ptr, name);
X    data_ptr            += ((strlen(name) + 2) >> 1) << 1;
X    info->entry[i].data  = data_ptr;
X
X    switch (type) {
X      case 's':
X        (void) strcpy(data_ptr, data);
X        break;
X
X      case 'l':
X        for (j = 0; j < sizeof(LOCK); j++)    /* Clear lock entry */
X          data_ptr[j] = '\0';
X        break;
X
X      case 'd':
X        for (j = 0; j < len; j++)             /* Clear data entry */
X          data_ptr[j] = '\0';
X        break;
X    }
X
X    data_ptr = data_ptr + len;
X    i++;
X  }
X  
X  (void) fclose(info_fp);
X
X  /*
X   * Create the event for SYSINFO
X   */
X  if ((info_event = _ev_creat(0, 1, -1, INFO_EVENT_NAME)) == -1) {
X    (void) munload(INFO_MODULE_NAME, 0x0400);
X    return(FAILED);
X  }
X}
X
X/*
X * m a i n
X */
Xmain(argc, argv)
X  int  argc;
X  char *argv[];
X{
X  int  i, j;
X  FILE *info_fp;
X  char *filename;
X  
X  filename = NULL;
X  
X  debug = 0;
X  
X  /*
X   * Parse command line arguments
X   */
X  for (i = 1 ; i < argc; i++)
X    if (argv[i][0] == '-')
X      for (j = 1; j < strlen(argv[i]); j++)
X        switch (tolower(argv[i][j])) {
X          case '?':     /* Usage */
X            usage();
X            exit(1);
X
X          case 'd':     /* Debug */
X            debug = 1;
X            if (argv[i][j+1] == '=')
X              j += 2;
X            else
X              j += 1;
X   
X            if (isdigit(argv[i][j])) {
X              debug = atoi(argv[i] + j);
X              while (isdigit(argv[i][j+1]))
X                j++;
X            }
X            break;
X
X          default:
X            usage();
X            exit(_errmsg(1, "unknown option '%c'\n", argv[i][j]));
X        }
X    else 
X      if (filename != NULL) {
X        usage();
X        exit(_errmsg(1, "only one path allowed\n"));
X      }
X      else
X        filename = argv[i];
X
X  if (filename == NULL)
X    filename = INFO_FILE_NAME;
X
X  if ((info_fp = fopen(filename, "r")) == NULL)
X    exit(_errmsg(errno, "can't open sysinfo file '%s'\n", filename));
X  
X  if (info_setup(info_fp) == -1)
X    exit(_errmsg(errno, "can't create sysinfo\n"));
X}
X
X/*
X * u s a g e
X */
Xvoid
Xusage()
X{
X  (void) fputs("Syntax: setup {<opts>} [<path>] {<opts>}\n", stderr);
X  (void) fputs("Function: setup sysinfo module with data from <path>\n", stderr);
X  (void) fputs("Options:\n", stderr);
X  (void) fputs("     -d[=][<num>]        debug mode (<num> is debug level)\n",
X               stderr);
X}
X
END_OF_FILE
if test 8038 -ne `wc -c <'setup.c'`; then
    echo shar: \"'setup.c'\" unpacked with wrong size!
fi
# end of 'setup.c'
fi
echo shar: End of archive 4 \(of 5\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
  |  Wolfgang Ocker          |  ocker@lan.informatik.tu-muenchen.dbp.de  |
  |  Lochhauserstr. 35a      |      pyramid!tmpmbx!recco!weo (home)      |
  |  D-8039 Puchheim         |     Technische Universitaet Muenchen      |
  |  Voice: +49 89 80 77 02  |          Huh, What? Where am I?           |