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? |