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 3 (of 5)."
# Contents: MAN/Sysinfo.prf MAN/Mdir.prf shell.c MAN/Utmp.prf
# chgrppass.c chpass.c MAN/Group.prf mdir.c grp.c strings.c
# MAN/Passwd.prf popen.c signal.a
# Wrapped by weo@recsys on Tue Oct 11 14:23:23 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MAN/Sysinfo.prf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MAN/Sysinfo.prf'\"
else
echo shar: Extracting \"'MAN/Sysinfo.prf'\" \(2686 characters\)
sed "s/^X//" >'MAN/Sysinfo.prf' <<'END_OF_FILE'
X.fill
X.justify
X.offset 5
X.rightmargin 55
X.pagesize 48
X.m1 2
X.m2 1
X.m3 2
X.m4 3
X.ec \
X.header /Sysinfo/OS9Lib/Sysinfo
X.footer /Page #//Printed (%)/
X.in +5
X.define topic
X.bold
X.in -5
X$1 $2 $3 $4 $5
X.in +5
X.en
X.define endtopic
X
X
X.en
X.define noform
X.nojustify
X.nofill
X.en
X.define noformend
X.justify
X.fill
X.en
X.! Manual created with MWB
X.! END-OF-MACRO
X.topic NAME
XSysinfo - Access the system-wide Parameters
X.endtopic
X.topic SYNOPSIS
X.noform
Xint info_type (name)
Xchar *name;
X
Xchar *info_str (name, str, len)
Xchar *name;
Xchar *str;
Xint len;
X
Xint info_num(name)
Xchar *name;
X
Xint info_is_locked (name)
Xchar *name;
X
Xint info_lock (name, signal)
Xchar *name;
Xint signal;
X
Xint info_unlock (name)
Xchar *name;
X
Xint info_change (name, signal)
Xchar *name;
Xint signal;
X.noformend
X.endtopic
X.topic DESCRIPTION
X The
X.ul
XSysinfo
Xconcept is complete new for OS9. Designed by TOP Munich and
Xwritten by Wolfgang Ocker, this concept provides the possibility to hold
Xsystem-wide information in a global data-module and allows the locking
Xof abstract `devices` like uucp etc. To access this module there
Xexists various functions.
X
X The function
X.ul
Xinfo_type()
Xaccepts a string and determines the kind of the entry by this name.
X.ul
Xinfo_str()
Xneeds a string with the name of the possible entry, a pointer to a
Xbuffer where the result will be copied to and the size of the buffer. It
Xextracts the string of the entry defined by the name and copies the
Xfound entry into the buffer.
X.ul
Xinfo_num()
Xaccepts a name and returns the value of the entry.
X.ul
Xinfo_is_locked()
Xneeds a string as an argument and returns the status of the given entry:
Xlocked by another process or free.
X.ul
Xinfo_lock
Xneeds two arguments, the first is the name of the entry, the second is a
Xsignal number with which the process can be killed. If another process
Xwants to lock the entry, the actual locking process will get a signal
Xwhich it has written in by info_lock. This process can make his clean-up
Xand then free the entry. If the signal number in the entry is -1, the
Xlocking process in unkillable.
X.ul
Xinfo_unlock()
Xallows to unlock an entry previous locked by this process. With
X.ul
Xinfo_change()
Xthe signal can be changed. This make sense when the process does some
Xcritical work.
X.endtopic
X.topic RETURN VALUE
XInfo_type returns the kind of the entry on success, -1 on failure.
XInfo_str returns a pointer to the buffer on success, NULL on failure.
XInfo_num returns the balue of the entry on success, -1 on failure.
XInfo_is_locked, info_lock, info_unlock and info_change returns 0 on success,
Xa negative value on failure.
X
X.endtopic
X.topic SEE ALSO
X.noform
XSysinfo, Setup, Getinfo
Xin the TOP Munich Release
X.noformend
X.endtopic
END_OF_FILE
if test 2686 -ne `wc -c <'MAN/Sysinfo.prf'`; then
echo shar: \"'MAN/Sysinfo.prf'\" unpacked with wrong size!
fi
# end of 'MAN/Sysinfo.prf'
fi
if test -f 'MAN/Mdir.prf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MAN/Mdir.prf'\"
else
echo shar: Extracting \"'MAN/Mdir.prf'\" \(3028 characters\)
sed "s/^X//" >'MAN/Mdir.prf' <<'END_OF_FILE'
X.fill
X.justify
X.offset 5
X.rightmargin 55
X.pagesize 48
X.m1 2
X.m2 1
X.m3 2
X.m4 3
X.ec \
X.header /Mdir/OS9Lib/Mdir
X.footer /Page #//Printed (%)/
X.in +5
X.define topic
X.bold
X.in -5
X$1 $2 $3 $4 $5
X.in +5
X.en
X.define endtopic
X
X
X.en
X.define noform
X.nojustify
X.nofill
X.en
X.define noformend
X.justify
X.fill
X.en
X.! Manual created with MWB
X.! END-OF-MACRO
X.topic NAME
XMdir - Access the Module Directory
X.endtopic
X.topic SYNOPSIS
X.noform
Xint _mopen()
X
Xint _mclose()
X
Xmentry *_mread()
X
Xint _mseek (position, place)
X
Xint position, place;
X
Xint _mtell()
X
Xint _mrewind()
X
Xmentry *_mexist(name)
Xchar *name;
X
Xchar *getmodname(mod_addr)
Xstruct modhcom *mod_addr;
X.noformend
X.endtopic
X.topic DESCRIPTION
X.bold
XMdir
Xprovides an easy way to handle access to the module directory. In
X.ul
Xmdir.h
Xa struct _mentry is defined to make the access as simple as possible.
X.in +5
X.nf
X.nj
Xtypedef struct _mentry {
X /* The name of the module */
X
X char m_name[33];
X /* The link count of the module */
X int m_link;
X
X /* A pointer to the module header */
X struct modhcom *m_ptr;
X
X /* A copy of the module header */
X struct modhcom m_head;
X} mentry;
X.fi
X.ju
X.in -5
X
X Before the first access to the module directory you should call
X.ul
X_mopen
Xto intialize some internal data. When finished with the access, call
X.ul
X_mclose
Xto make sure that everything is cleaned up properly.
X.ul
X_mread
Xreturns the next entry in the module directory. If there is no further
Xentry found, NULL is returned.
X.ul
X_mseek
Xallows the user to seek randomly through the module directory. If place
Xis 0, the seek operation takes place from the start of the module
Xdirectory, if it is 1, it starts from the current position and if it is
X2 it seeks after the last entry in the module directory.
X.ul
X_mtell
Xreturns the current position in the module directory.
X.ul
X_mrewind
Xmoves the pointer back to the beginning of the directory.
X.ul
X_mexist
Xscans through the module directory to see, whether the module `name` has an
Xentry there.
X.ul
Xgetmodname
Xrequires a pointer to a module header and returns the name of the module
Xif found, NULL otherwise.
X.endtopic
X.topic CAVEATS
X_mseek() and _mtell() assuming that every next position has a distance
Xof 1 to the previous, not sizeof (mentry).
X.endtopic
X.topic RETURN VALUE
X_mopen(), mclose() and _mrewind() return 0 on success and -1 on failure.
X_mread() returns the next entry or NULL if the last one has proceeded or
Xon failure. _mseek() returns the new position of the pointer on
Xsuccess, -1 on failure. _mtell() returns the current position of the
Xpointer on success or -1 on failure. _mexist() returns a pointer to the
Xmentry of the module, if found, else NULL. Getmodname() returns the name
Xof the module on success, NULL otherwise.
X
X.endtopic
X.topic EXAMPLES
X.noform
X# include <mdir.h>
X
Xmentry *entry;
X
Xif (_mopen() < 0)
X return;
Xwhile (entry = _mread ())
X printf ("%s\\n", entry->m_name);
X(void) _mclose ();
X.noformend
X.endtopic
X.topic SEE ALSO
X.noform
XMdir
Xin the OS9 User Manual
X.noformend
X.endtopic
END_OF_FILE
if test 3028 -ne `wc -c <'MAN/Mdir.prf'`; then
echo shar: \"'MAN/Mdir.prf'\" unpacked with wrong size!
fi
# end of 'MAN/Mdir.prf'
fi
if test -f 'shell.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'shell.c'\"
else
echo shar: Extracting \"'shell.c'\" \(3281 characters\)
sed "s/^X//" >'shell.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib: shell(), xshell()
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 <modes.h>
X#include <strings.h>
X#include <errno.h>
X
X
Xextern char **environ;
Xextern int os9forkc();
X
Xextern char *findmod(), *getenv(), *info_str();
X
Xstatic char cmd_name[600];
X
Xint _shell_secure = 0;
X
Xstatic int check_shell()
X{
X char *shell, *cp, *cp2, *cp3, val_shell[200];
X
X errno = E_FNA;
X
X if ((shell = getenv("SHELL")) == NULL)
X return(0);
X
X if (info_str("valid.shells", val_shell, sizeof(val_shell)) == NULL)
X strcpy(val_shell, "shell,sh,csh");
X
X for (cp = val_shell; cp != NULL && *cp != '\0'; ) {
X cp2 = cp;
X if ((cp = index(cp, ',')) != NULL)
X *cp++ = '\0';
X
X while (*cp2 == ' ')
X cp2++;
X if ((cp3 = index(cp2, ' ')) != NULL)
X *cp3 = '\0';
X
X if (!strcmp(shell, cp2))
X return(1);
X }
X
X return(0);
X}
X
X/*
X * s h e l l
X */
Xint shell(name)
X char *name;
X{
X static char *argv[] = {NULL, NULL, NULL };
X static char cmd[300], cmd_path[100];
X register char *cp;
X int pid, status;
X
X if (_shell_secure)
X if (!check_shell())
X return(-1);
X
X cp = name;
X while (*cp == ' ')
X cp++;
X
X strcpy(cmd_path, cp);
X
X if (cp = index(cmd_path, ' '))
X *cp++ = '\0';
X
X strcpy(cmd, "ex ");
X strcat(cmd, findmod(cmd_path, cmd_path));
X if (cp) {
X strcat(cmd, " ");
X strcat(cmd, name+(cp-cmd_path));
X }
X
X argv[1] = cmd;
X
X argv[0] = findmod("shell", "SYSTEM.SHELL");
X if ((pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3)) == -1)
X return(-1);
X
X
X while (wait(&status) != pid) ;
X
X if (status &= 0x0ffff) {
X errno = status;
X return(-1);
X }
X else
X return(0);
X}
X
X/*
X * x s h e l l
X */
Xint xshell(name)
X register char *name;
X{
X register int pid;
X int status;
X char **argv;
X
X if (_shell_secure)
X if (!check_shell())
X return(-1);
X
X strcpy(cmd_name, name);
X if (getargs(cmd_name, &argv) == -1)
X return(-1);
X
X if ((pid = os9exec(os9forkc, findmod(argv[0], argv[0]), argv, environ,
X 0, 0, 3)) == -1) {
X free(argv);
X return(-1);
X }
X
X free(argv);
X
X while (wait(&status) != pid) ;
X
X if (status &= 0x0ffff) {
X errno = status;
X return(-1);
X }
X else
X return(0);
X}
X
END_OF_FILE
if test 3281 -ne `wc -c <'shell.c'`; then
echo shar: \"'shell.c'\" unpacked with wrong size!
fi
# end of 'shell.c'
fi
if test -f 'MAN/Utmp.prf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MAN/Utmp.prf'\"
else
echo shar: Extracting \"'MAN/Utmp.prf'\" \(3486 characters\)
sed "s/^X//" >'MAN/Utmp.prf' <<'END_OF_FILE'
X.fill
X.justify
X.offset 5
X.rightmargin 55
X.pagesize 48
X.m1 2
X.m2 1
X.m3 2
X.m4 3
X.ec \
X.header /Utmp/OS9Lib/Utmp
X.footer /Page #//Printed (%)/
X.in +5
X.define topic
X.bold
X.in -5
X$1 $2 $3 $4 $5
X.in +5
X.en
X.define endtopic
X
X
X.en
X.define noform
X.nojustify
X.nofill
X.en
X.define noformend
X.justify
X.fill
X.en
X.! Manual created with MWB
X.! END-OF-MACRO
X.topic NAME
XUtmp - Library to examine the /dd/SYS/utmp file
X.endtopic
X.topic SYNOPSIS
X.noform
Xint _utmp_stat (stat)
Xchar *stat;
X
Xint _utmp_write (type, name, line, pid, status, uid, gid)
Xint type;
Xchar *name;
Xchar *line;
Xint pid;
Xchar *status;
Xint uid;
Xint gid;
X
Xstruct utmp *getutent ()
X
Xint setutent ()
X
Xint endutent ()
X
Xstruct utmp *getutid (id)
Xstruct utmp *id;
X
Xstruct utmp *getutline (line)
Xstruct utmp *line;
X
Xint pututline (utmp)
Xstruct utmp *utmp;
X
Xvoid utmpname (file)
Xchar *file;
X.noformend
X.endtopic
X.topic DESCRIPTION
XThe utmp-library offers the programmers a set of functions to have an
Xeasy access to the
X.ul
X/dd/SYS/utmp
Xfile or files which looks like this (e.g. /h0/SYS/wtmp). For these
Xfunction there is a
X.ul
Xstruct utmp
Xdefinied in utmp.h:
X.nf
X.nj
X.in +5
Xstruct utmp {
X /* User login name */
X char ut_user[33];
X
X /* /etc/lines id (usually line #) */
X char ut_id[4];
X
X /* device name (console, lnxx) */
X char ut_line[33];
X
X /* process id */
X short ut_pid;
X
X /* User ID, Group ID */
X short ut_uid, ut_gid;
X
X /* Baud rate */
X int ut_baud;
X
X /* type of entry */
X short ut_type;
X
X /* time entry was made */
X time_t ut_time;
X
X /* Flags */
X char ut_status[10];
X};
X.in -5
X.justify
X.fill
X
X To initialize the access to /dd/SYS/utmp you should call the
Xfunction
X.bold
Xsetutent()
Xwhich opens or rewinds the file. When you have finished your access to
Xthis file you should call
X.bold
Xendutent()
Xto close the file. The function
X.bold
Xgeturent()
Xfetches the next entry of the utmp file and returns a pointer to the
Xstruct utmp which has been filled by this function.
X.bold
XGetutid()
Xrequires a struct utmp where the entry
X.ul
Xut_type
Xis set to the value you look for,
X.bold
Xgetutline()
Xneeds also a struct utmp with
X.ul
Xut_line
Xset to the required contents. With
X.bold
Xpututline()
Xan entry will be added in a free slot of the current file.
X.bold
XUtmpname()
Xrequires a file name and all other operations then take place on this
Xfile instead of the /dd/SYS/utmp.
X
X There also exist some internal function which may be useful for
Xsome reasons.
X.bold
X_utmp_stat()
Xrequires a string with flags and changes the current flags for this
Xline.
X.bold
X_utmp_write()
Xis the most used internal function. The struct utmp is filled up with
Xthe arguments and then the entry will be written to the utmp file or
Xthey will be deleted from there if
X.ul
Xtype
Xis EMPTY (definied in utmp.h).
X.endtopic
X.topic CAVEATS
XThe functions getutent(), getutid() and getutline() returns pointer to
Xstatic data which will be overwritten by each call of one of these
Xfunctions.
X.endtopic
X.topic RETURN VALUE
X_utmp_stat(), _utmp_write(), setutent (), endutent (), pututline ()
Xreturning 0 on success, -1 on failure. Getutent(), getutid(),
Xgetutline() returning pointer to struct utmp on success, NULL on
Xfailure.
X
X.endtopic
X.topic FILES
X.noform
X/dd/SYS/utmp
X.in +5
XThe standard utmp file.
X.in -5
X.noformend
X.endtopic
X.topic SEE ALSO
X.noform
XLogon and mmon
Xin the Documentation of the Top Release.
X.noformend
X.endtopic
END_OF_FILE
if test 3486 -ne `wc -c <'MAN/Utmp.prf'`; then
echo shar: \"'MAN/Utmp.prf'\" unpacked with wrong size!
fi
# end of 'MAN/Utmp.prf'
fi
if test -f 'chgrppass.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'chgrppass.c'\"
else
echo shar: Extracting \"'chgrppass.c'\" \(3674 characters\)
sed "s/^X//" >'chgrppass.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib: change_grppasswd()
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 <modes.h>
X#include <grp.h>
X#include <strings.h>
X
Xextern struct group *_getgr();
Xextern char *crypt();
X
Xstatic struct group group;
Xstatic char line[256];
X
X/*
X * c h a n g e _ g r p p a s s w d
X */
Xchange_grppasswd (name, password)
X char *name, *password;
X{
X char *cryptpw;
X int found, pos, Count;
X struct group *gr;
X int grfd, tmpfd;
X char tmpname[256], tmp[256];
X char *cp1, *cp2;
X
X /*
X * Group-File fuer Update oeffnen
X */
X if ((grfd = open(GROUP, S_IREAD+S_IWRITE)) < 0)
X return(-1);
X
X found = 0;
X
X /*
X * zunaechst suchen wir im Password-File den Eintrag fuer den User
X */
X while (pos = lseek(grfd, 0, 1), (Count = readln(grfd, line, BUFSIZ)) > 0) {
X line[Count] = '\0';
X gr = _getgr(&group, line);
X
X if (gr && (!_strccmp(name, gr->gr_name))) {
X found = 1;
X break;
X }
X }
X
X if (!found)
X return(-1);
X
X /*
X * erstes Colon suchen (danach steht das Passwort)
X */
X if (!(cp1 = index(line, ':'))) {
X close(grfd);
X return(-1);
X }
X
X if (!(cp2 = index(cp1+1, ':'))) {
X close(grfd);
X return(-1);
X }
X
X if (strlen(password))
X if (strlen(gr->gr_passwd) < 2)
X cryptpw = crypt(password, _rnd_salt());
X else
X cryptpw = crypt(password, gr->gr_passwd);
X
X if (cp2-cp1 == 15) {
X /*
X * Passwort einkopieren
X */
X for (cp1 += 1; cp1 < cp2; cp1++)
X *cryptpw++ = *cp1;
X
X lseek(grfd, -Count, 1);
X writeln(grfd, line, strlen(line));
X close(grfd);
X return(0);
X }
X else {
X _ss_lock(grfd, -1);
X lseek(grfd, 0, 0);
X
X sprintf(tmpname, "/dd/grXXXXXX");
X mktemp(tmpname);
X
X if ((tmpfd = creat(tmpname, S_IREAD+S_IWRITE)) < 0) {
X close(grfd);
X return(-1);
X }
X
X while (lseek(grfd, 0, 1) != pos) {
X Count = readln(grfd, tmp, BUFSIZ);
X writeln(tmpfd, tmp, Count);
X }
X
X write(tmpfd, line, cp1-line+1);
X if (strlen(password))
X write(tmpfd, cryptpw, strlen(cryptpw));
X
X /*
X * ein bisschen trickreich: wir schreiben bis zum CR!!
X */
X writeln(tmpfd, cp2, strlen(line));
X
X Count = readln(grfd, tmp, BUFSIZ);
X
X while ((Count = readln(grfd, tmp, BUFSIZ)) > 0)
X writeln(tmpfd, tmp, Count);
X close(tmpfd);
X
X if ((tmpfd = open(tmpname, S_IREAD)) < 0)
X return(-1);
X
X lseek(grfd, 0, 0);
X while ((Count = readln(tmpfd, tmp, BUFSIZ)) > 0)
X writeln(grfd, tmp, Count);
X close(tmpfd);
X _ss_size(grfd, lseek(grfd, 0, 1));
X close(grfd);
X
X unlink(tmpname);
X return(0);
X }
X}
END_OF_FILE
if test 3674 -ne `wc -c <'chgrppass.c'`; then
echo shar: \"'chgrppass.c'\" unpacked with wrong size!
fi
# end of 'chgrppass.c'
fi
if test -f 'chpass.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'chpass.c'\"
else
echo shar: Extracting \"'chpass.c'\" \(3714 characters\)
sed "s/^X//" >'chpass.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib: change_passwd()
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 <modes.h>
X#include <pwd.h>
X#include <strings.h>
X
Xextern struct passwd *_getpw();
Xextern char *crypt();
X
Xstatic char *PASS = "/h0/SYS/password";
Xstatic struct passwd passwd;
Xstatic char line[256];
X
X/*
X * c h a n g e _ p a s s w d
X */
Xchange_passwd(name, password)
X char *name, *password;
X{
X char *cryptpw;
X int found, pos, Count;
X struct passwd *pw;
X int pwfd, tmpfd;
X char tmpname[256], tmp[256];
X char *cp1, *cp2;
X
X /*
X * Passwort-File fuer Update oeffnen
X */
X if ((pwfd = open(PASS, S_IREAD+S_IWRITE)) < 0)
X return(-1);
X
X found = 0;
X
X /*
X * zunaechst suchen wir im Password-File den Eintrag fuer den User
X */
X while (pos = lseek(pwfd, 0, 1), (Count = readln(pwfd, line, BUFSIZ)) > 0) {
X line[Count] = '\0';
X pw = _getpw(&passwd, line);
X
X if (pw && (!_strccmp(name, pw->pw_name))) {
X found = 1;
X break;
X }
X }
X
X if (!found)
X return(-1);
X
X /*
X * erstes Komma suchen (danach steht das Passwort)
X */
X if (!(cp1 = index(line, ','))) {
X close(pwfd);
X return(-1);
X }
X
X if (!(cp2 = index(cp1+1, ','))) {
X close(pwfd);
X return(-1);
X }
X
X if (strlen(password))
X if (strlen(pw->pw_passwd) < 2)
X cryptpw = crypt(password, _rnd_salt());
X else
X cryptpw = crypt(password, pw->pw_passwd);
X
X if (cp2-cp1 == 15) {
X /*
X * Passwort einkopieren
X */
X for (cp1 += 1; cp1 < cp2; cp1++)
X *cryptpw++ = *cp1;
X
X lseek(pwfd, -Count, 1);
X writeln(pwfd, line, strlen(line));
X close(pwfd);
X return(0);
X }
X else {
X _ss_lock(pwfd, -1);
X lseek(pwfd, 0, 0);
X
X sprintf(tmpname, "/dd/pwXXXXXX");
X mktemp(tmpname);
X
X if ((tmpfd = creat(tmpname, S_IREAD+S_IWRITE)) < 0) {
X close(pwfd);
X return(-1);
X }
X
X while (lseek(pwfd, 0, 1) != pos) {
X Count = readln(pwfd, tmp, BUFSIZ);
X writeln(tmpfd, tmp, Count);
X }
X
X write(tmpfd, line, cp1-line+1);
X if (strlen(password))
X write(tmpfd, cryptpw, strlen(cryptpw));
X
X /*
X * ein bisschen trickreich: wir schreiben bis zum CR!!
X */
X writeln(tmpfd, cp2, strlen(line));
X
X Count = readln(pwfd, tmp, BUFSIZ);
X
X while ((Count = readln(pwfd, tmp, BUFSIZ)) > 0)
X writeln(tmpfd, tmp, Count);
X close(tmpfd);
X
X if ((tmpfd = open(tmpname, S_IREAD)) < 0)
X return(-1);
X
X lseek(pwfd, 0, 0);
X while ((Count = readln(tmpfd, tmp, BUFSIZ)) > 0)
X writeln(pwfd, tmp, Count);
X close(tmpfd);
X _ss_size(pwfd, lseek(pwfd, 0, 1));
X close(pwfd);
X
X unlink(tmpname);
X return(0);
X }
X}
END_OF_FILE
if test 3714 -ne `wc -c <'chpass.c'`; then
echo shar: \"'chpass.c'\" unpacked with wrong size!
fi
# end of 'chpass.c'
fi
if test -f 'MAN/Group.prf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MAN/Group.prf'\"
else
echo shar: Extracting \"'MAN/Group.prf'\" \(3933 characters\)
sed "s/^X//" >'MAN/Group.prf' <<'END_OF_FILE'
X.fill
X.justify
X.offset 5
X.rightmargin 55
X.pagesize 48
X.m1 2
X.m2 1
X.m3 2
X.m4 3
X.ec \
X.header /Group/OS9Lib/Group
X.footer /Page #//Printed (%)/
X.in +5
X.define topic
X.bold
X.in -5
X$1 $2 $3 $4 $5
X.in +5
X.en
X.define endtopic
X
X
X.en
X.define noform
X.nojustify
X.nofill
X.en
X.define noformend
X.justify
X.fill
X.en
X.! Manual created with MWB
X.! END-OF-MACRO
X.topic NAME
XGroup - Functions to examine the Groupfile /dd/SYS/group
X.endtopic
X.topic SYNOPSIS
X.noform
X# include <stdio.h>
X# include <grp.h>
X
Xint _grp_secure;
Xint setgrent ()
X
Xint endgrent ()
X
Xstruct group *_getgr (group, line)
Xstruct group *group;
Xchar *line;
X
Xstruct group *getgrent ()
X
Xstruct group *getgrgid (gid)
Xint gid;
X
Xstruct group *getgrnam (name)
Xchar *name;
X
Xstruct group *fgetgrent(f)
XFILE *f;
X
Xint getgroups (num, gids)
Xint num;
Xint *gids;
X.noformend
X.endtopic
X.topic DESCRIPTION
XThe
X.bold
Xgroup
Xlibrary helps to access the group file which is normally located in
X/dd/SYS/group and on the bootdevice in /SYS/group. A line in the file
Xhas four entries, seperated by a colon ':'. The first entry is the name
Xof the group, the second is a password, the third is the group-ID and
Xthe fourth entry is a list of users who are allowed to change to this
Xgroup via newgrp. To access the group file there are various functions.
XWith
X.ul
Xsetgrent ()
Xyou can open or rewind the groupfile,
X.ul
Xendgrent ()
Xcloses the group file (don't forget this!). You should declare an
Xexternal variable
X.bold
X_grp_secure
Xwhich should be set to a non-zero value if you want to access the group
Xfile on the bootdevice, otherwise the group file is searched on the
Xdefault-disk /dd. Most of the other functions
Xreturn a
X.ul
Xstruct group
Xwhich is definied in
X.bold
Xgrp.h
Xand loooks like this:
X.br
X.nf
X.nj
X.in +5
Xstruct group {
X char *gr_name;
X char *gr_passwd;
X int gr_gid;
X char **gr_mem;
X};
X.in -5
X.fill
X.justify
X
X struct group *_getgr(group, line)
X register struct group *group;
X char *line;
X The internal function _getgr () my be useful if you have a line
Xwhich looks like an entry in the group file and you want to seperate it.
XAs argument the function requires a pointer a struct group where the
Xresult will be copied to and the line, defined as a pointer of char.
X
X If you just want to scan through the group file the function
X.ul
Xgetgrent ()
Xreturns the next entry in the group file. To determine the entry for a
Xspecified group-ID you can use
X.ul
Xgetgrgid ()
Xwhich looks for the entry with the given ID. If you have the group name,
Xuse
X.ul
Xgetgrnam ()
Xto get the entry in the group file.
X.ul
Xfgetgrent ()
Xis the same function as getgrent (), but you can pass over a file
Xpointer to another file which has the same structure as the group file.
X
X The function
X.ul
Xgetgroups
Xglances through the group file and returns all valid group-IDs or
Xmaximum
X.bold
Xnum
Xentries if there are more. The IDs are filled in the area
X.bold
Xgids
Xwhich have to be passed to this function and must be a pointer to int.
X.endtopic
X.topic CAVEATS
X The functions getgrent(), getgrgid(), getgrnam() and fgetgrent()
Xreturn pointer to static data which will be overwritten by each call of
Xthe function.
X.endtopic
X.topic RETURN VALUE
X The functions setgrent() and endgrent() return 0 on success and
X-1 on failure. The functions _getgr(), getgrent(), getgrgid(),
Xgetgrnam() and fgetgrent() returns a pointer to a struct group on
Xsuccess or NULL on failure. Getgroups returns -1 on failure or the number
Xof entries which are returned in the given pointer gids.
X
X.endtopic
X.topic FILES
X.noform
X/dd/SYS/group
X/<bootdrv>/SYS/group
X.noformend
X.endtopic
X.topic EXAMPLES
X.noform
X# include <grp.h>
X
Xstruct group *gr;
X
Xif ((gr = getgrnam ("root")) == NULL)
X return (-1);
Xelse
X return (gr->gr_gid ? -1 : 0);
X.noformend
X.endtopic
X.topic SEE ALSO
X.noform
Xnewgrp, change_grppasswd
Xin the Top Munich Release and
Xthe Passwd Library, change_grppasswd
Xin the Top OS9Lib Documentation.
X.noformend
X.endtopic
END_OF_FILE
if test 3933 -ne `wc -c <'MAN/Group.prf'`; then
echo shar: \"'MAN/Group.prf'\" unpacked with wrong size!
fi
# end of 'MAN/Group.prf'
fi
if test -f 'mdir.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mdir.c'\"
else
echo shar: Extracting \"'mdir.c'\" \(4013 characters\)
sed "s/^X//" >'mdir.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib: module directory 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
X#include <stdio.h>
X#include <mdir.h>
X
X/* Module-Directory entry */
Xtypedef struct {
X struct modhcom *md_mptr;
X long md_group;
X long md_static;
X short md_link;
X short md_mchk;
X} ModDir;
X
X#define TRUE 1
X#define FALSE 0
X
Xstatic mentry ret;
Xstatic ModDir *head = NULL;
Xstatic int pos;
Xstatic int count, max;
Xstatic int size;
X
X/*
X * _ m o p e n
X */
Xint _mopen()
X{
X register int maxcount;
X
X size = sizeof(ModDir);
X maxcount = 0;
X if (head)
X _mclose();
X
X head = NULL;
X
X do {
X maxcount += 80;
X if (!(head = (ModDir *) realloc(head, maxcount * size + 2)))
X return(-1);
X } while ((count = _get_module_dir(head, maxcount * size + 2)) >
X maxcount * size);
X
X max = count / size;
X pos = 0;
X return(0);
X}
X
X/*
X * _ m c l o s e
X */
Xint _mclose()
X{
X if (head) {
X free(head);
X head = NULL;
X return(0);
X }
X else
X return(-1);
X}
X
X/*
X * _ m r e a d
X */
Xmentry *_mread()
X{
X register struct modhcom *md;
X
X if ((!head) || (pos >= max))
X return(NULL);
X
X while ((pos < max) && (head[pos].md_mptr == NULL))
X ++pos;
X
X if (pos >= max)
X return(NULL);
X
X md = head[pos].md_mptr;
X ret.m_ptr = md;
X _cpymem(0, sizeof(struct modhcom), md, &ret.m_head);
X _cpymem(0, sizeof(ret.m_name), (char *) md + ret.m_head._mname, ret.m_name);
X
X ret.m_link = head[pos].md_link;
X ++pos;
X return(&ret);
X}
X
X/*
X * _ m s e e k
X */
Xint _mseek(position, place)
X int position, place;
X{
X int t;
X
X if ((place < 0) || (place > 2) || (!head))
X return(-1);
X
X switch (place) {
X case 0:
X if ((position >= 0) && (position < max))
X pos = position;
X else
X return(-1);
X break;
X
X case 1:
X t = pos + position;
X if ((t >= 0) && (t < max))
X pos = t;
X else
X return(-1);
X break;
X
X case 2:
X t = max -1 + position;
X if ((t >= 0) && (t < max))
X pos = t;
X else
X return(-1);
X break;
X
X default:
X return(-1);
X }
X return(pos);
X}
X
X/*
X * _ m t e l l
X */
Xint _mtell()
X{
X if (!head)
X return(-1);
X else
X return(pos);
X}
X
X/*
X * _ m r e w i n d
X */
Xint _mrewind()
X{
X if (!head)
X return(-1);
X
X pos = 0;
X return(0);
X}
X
X/*
X * _ m e x i s t
X */
Xmentry *_mexist(name)
X register char *name;
X{
X register mentry *scan;
X register int siz;
X int found;
X
X found = FALSE;
X if (_mopen() < 0)
X return(NULL);
X
X siz = strlen(name);
X while (scan = _mread())
X if (!_cmpnam(scan->m_name, name, siz)) {
X found = TRUE;
X break;
X }
X
X _mclose();
X return(found ? scan : NULL);
X}
X
X/*
X * g e t m o d n a m e
X */
Xchar *getmodname(mod_addr)
X register struct modhcom *mod_addr;
X{
X register mentry *mentry;
X
X if (_mopen() == -1)
X return(NULL);
X
X while ((mentry = _mread()) != NULL)
X if (mod_addr == mentry->m_ptr)
X return(mentry->m_name);
X
X return(NULL);
X}
END_OF_FILE
if test 4013 -ne `wc -c <'mdir.c'`; then
echo shar: \"'mdir.c'\" unpacked with wrong size!
fi
# end of 'mdir.c'
fi
if test -f 'grp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'grp.c'\"
else
echo shar: Extracting \"'grp.c'\" \(4275 characters\)
sed "s/^X//" >'grp.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib: group 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 <grp.h>
X
Xstatic FILE *grpf = NULL;
Xstatic char line[BUFSIZ+1];
Xstatic char *member[MAX_MEM+1];
Xstatic struct group group;
X
X#define TRUE (-1)
X#define FALSE (0)
X
Xint _grp_secure = 0;
X
Xextern FILE *ddfopen();
X
X/*
X * s e t g r e n t
X */
Xint setgrent()
X{
X char fn[100];
X
X if (!grpf) {
X if (!(grpf = ddfopen(GROUP, fn, "r", _grp_secure)))
X return(-1);
X }
X else
X rewind(grpf);
X
X return(0);
X}
X
X/*
X * e n d g r e n t
X */
Xvoid endgrent()
X{
X if (grpf) {
X fclose (grpf);
X grpf = NULL;
X }
X}
X
X/*
X * g r s k i p
X */
Xstatic char *grskip(p)
X register char *p;
X
X{
X while (*p && *p != ':')
X ++p;
X if (*p)
X *p++ = '\0';
X return(p);
X}
X
X/*
X * g r s k i p 2
X */
Xstatic char *grskip2 (p)
X register char *p;
X
X{
X while (*p && (*p != ',') && (*p != '\n'))
X ++p;
X
X if (*p)
X if (*p != '\n')
X *p++ = '\0';
X else
X *p = '\0';
X
X return(p);
X}
X
X/*
X * _ g e t g r
X */
Xstruct group *_getgr(gr, grline)
X register struct group *gr;
X char *grline;
X
X{
X register char *p;
X char *cp;
X int t;
X static char tmp[BUFSIZ+1];
X
X strcpy(tmp, grline);
X
X p = tmp;
X gr->gr_name = p;
X
X p = grskip(p);
X gr->gr_passwd = p;
X
X p = grskip(p);
X cp = p;
X
X p = grskip(p);
X gr->gr_gid = atoi(cp);
X t = 0;
X while ((t < MAX_MEM) && *p) {
X member[t++] = p;
X p = grskip2(p);
X }
X
X member[t] = NULL;
X gr->gr_mem = member;
X while(*p && *p != '\n')
X p++;
X *p = '\0';
X return(gr);
X}
X
X/*
X * g e t g r e n t
X */
Xstruct group *getgrent()
X{
X if (!grpf)
X if (setgrent() < 0)
X return(NULL);
X
X do {
X if (!fgets(line, BUFSIZ,grpf))
X return(NULL);
X } while (line[0] == '#' || line[0] == '*');
X
X if (!_getgr(&group, line))
X return(NULL);
X
X return(&group);
X}
X
X/*
X * g e t g r g i d
X */
Xstruct group *getgrgid (gid)
X int gid;
X
X{
X int found = 0;
X
X if (setgrent() < 0)
X return(NULL);
X
X while ((!found) && fgets(line, BUFSIZ, grpf)) {
X if (line[0] == '#' || line[0] == '*')
X continue;
X if (_getgr(&group, line))
X found = (group.gr_gid == gid);
X }
X
X if (found)
X return(&group);
X else
X return(NULL);
X}
X
X/*
X * g e t g r n a m
X */
Xstruct group *getgrnam(name)
X char *name;
X
X{
X int found = 0;
X
X if (setgrent() < 0)
X return(NULL);
X
X while ((!found) && fgets(line, BUFSIZ, grpf)) {
X if (line[0] == '#' || line[0] == '*')
X continue;
X if (_getgr(&group, line))
X found = (!_strccmp(group.gr_name, name));
X }
X
X if (found)
X return(&group);
X else
X return(NULL);
X}
X
X/*
X * f g e t g r e n t
X */
Xstruct group *fgetgrent(f)
X FILE *f;
X
X{
X struct group *gr = NULL;
X
X do {
X if (fgets(line, BUFSIZ, f))
X gr = _getgr(line, &group);
X else
X gr = NULL;
X } while (gr && (line[0] == '#' || line[0] == '*'));
X
X return(gr);
X}
X
X/*
X * g e t g r o u p s
X */
Xint getgroups(num, gids)
X int num;
X int *gids;
X{
X struct group *gr;
X int i;
X
X if (setgrent() < 0)
X return(-1);
X
X for (i = 0; i < num; i++)
X if (!(gr = getgrent())) {
X endgrent();
X return(i);
X }
X else
X gids[i] = gr->gr_gid;
X
X endgrent();
X return(num);
X}
END_OF_FILE
if test 4275 -ne `wc -c <'grp.c'`; then
echo shar: \"'grp.c'\" unpacked with wrong size!
fi
# end of 'grp.c'
fi
if test -f 'strings.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'strings.c'\"
else
echo shar: Extracting \"'strings.c'\" \(4370 characters\)
sed "s/^X//" >'strings.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <strings.h>
X
X/* strcspn(3)
X *
X * Author: Terrence W. Holm July 1988
X *
X *
X * This function determines the length of a span from the
X * beginning of <string> which contains none of the
X * characters specified in <char_set>. The length of the
X * span is returned.
X */
X
X
Xint strcspn(string, char_set)
X char *string;
X char *char_set;
X{
X register char *str;
X register char *chr;
X
X if (string == NULL)
X return(0);
X
X if (char_set == NULL)
X return(strlen(string));
X
X for (str = string; *str != '\0'; ++str)
X for (chr = char_set; *chr != '\0'; ++chr)
X if (*str == *chr)
X return(str - string);
X
X return(str - string);
X}
X
X
X
X/* strpbrk(3)
X *
X * Author: Terrence W. Holm July 1988
X *
X *
X * Strpbrk(3) scans <string> for the first occurrence of a
X * character from the string <char_set>. If a character from
X * the <char_set> was found then a pointer to it within
X * <string> is returned, otherwise NULL is returned.
X */
X
Xchar *strpbrk(string, char_set)
X char *string;
X char *char_set;
X{
X register char c;
X register char *p;
X
X if (string == NULL || char_set == NULL)
X return(NULL);
X
X while ((c = *string++) != '\0')
X for (p = char_set; *p != '\0'; ++p)
X if (c == *p)
X return(string - 1);
X
X return(NULL);
X}
X
X
X
X/* strspn(3)
X *
X * Author: Terrence W. Holm July 1988
X *
X *
X * This function determines the length of a span from the
X * beginning of <string> which contains only characters
X * specified in <char_set>. The length of the span is
X * returned.
X */
X
Xint strspn(string, char_set)
X char *string;
X char *char_set;
X{
X register char *str;
X register char *chr;
X
X if (string == NULL || char_set == NULL)
X return(0);
X
X for (str = string; *str != '\0'; ++str) {
X for (chr = char_set; *chr != '\0'; ++chr)
X if (*str == *chr)
X break;
X
X if (*chr == '\0')
X return(str - string);
X }
X
X return(str - string);
X}
X
X
X/* strstr(3)
X *
X * Author: Terrence W. Holm July 1988
X *
X *
X * Finds the first occurrence of a substring, pointed to by
X * <substr>, within a string pointed to by <string>.
X * If the substring is found then a pointer to it within
X * <string> is returned, otherwise NULL is returned.
X */
X
X
Xchar *strstr(string, substr)
X char *string;
X char *substr;
X{
X register char head_string;
X register char head_substr;
X
X if (string == NULL || substr == NULL)
X return(NULL);
X
X head_substr = *substr++;
X
X while ((head_string = *string++) != '\0')
X if (head_string == head_substr) {
X register char *tail_string = string;
X register char *tail_substr = substr;
X
X do {
X if (*tail_substr == '\0')
X return(string - 1);
X } while (*tail_string++ == *tail_substr++);
X }
X
X return(NULL);
X}
X
X/* strtok(3)
X *
X * Author: Terrence W. Holm July 1988
X *
X *
X * This function is used to divide up a string into tokens.
X * Strtok(3) is called with <string> pointing to the string
X * to be scanned and <char_set> pointing to a string which
X * consists of the set of separator characters. Tokens are
X * substrings bordered by separator characters. A pointer to
X * the first token encountered is returned. If <string> is
X * NULL then the scan is continued from the last token
X * returned. Each token is terminated by a '\0'. If there are
X * no tokens remaining in the string then NULL is returned.
X */
X
Xchar *strtok(string, char_set)
X char *string;
X char *char_set;
X{
X static char *last_string = "";
X register char *chr;
X char *next_token;
X
X if (string == NULL)
X string = last_string;
X
X if (char_set == NULL)
X return(NULL);
X
X
X /* First skip over any separator characters */
X
X while (*string != '\0') {
X for (chr = char_set; *chr != '\0'; ++chr)
X if (*string == *chr)
X break;
X
X if (*chr == '\0')
X break;
X
X ++string;
X }
X
X
X /* Check if we have reached the end of the string */
X
X if (*string == '\0')
X return(NULL);
X
X /* If not, then we have found the next token */
X
X next_token = string;
X
X
X /* Scan for the end of this token */
X
X while (*string != '\0') {
X for (chr = char_set; *chr != '\0'; ++chr)
X if (*string == *chr) {
X *string = '\0';
X last_string = string + 1;
X return(next_token);
X }
X
X ++string;
X }
X
X last_string = string;
X return(next_token);
X }
END_OF_FILE
if test 4370 -ne `wc -c <'strings.c'`; then
echo shar: \"'strings.c'\" unpacked with wrong size!
fi
# end of 'strings.c'
fi
if test -f 'MAN/Passwd.prf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MAN/Passwd.prf'\"
else
echo shar: Extracting \"'MAN/Passwd.prf'\" \(4722 characters\)
sed "s/^X//" >'MAN/Passwd.prf' <<'END_OF_FILE'
X.fill
X.justify
X.offset 5
X.rightmargin 55
X.pagesize 48
X.m1 2
X.m2 1
X.m3 2
X.m4 3
X.ec \
X.header /Passwd/OS9Lib/Passwd
X.footer /Page #//Printed (%)/
X.in +5
X.define topic
X.bold
X.in -5
X$1 $2 $3 $4 $5
X.in +5
X.en
X.define endtopic
X
X
X.en
X.define noform
X.nojustify
X.nofill
X.en
X.define noformend
X.justify
X.fill
X.en
X.! Manual created with MWB
X.! END-OF-MACRO
X.topic NAME
XPasswd - Access the password file
X.endtopic
X.topic SYNOPSIS
X.noform
X# include <pwd.h>
X
Xint _pw_secure;
X
Xint setpwent()
X
Xint endpwent()
X
Xstruct passwd *_getpw(passwd, line)
Xstruct passwd *passwd;
Xchar *line;
X
Xstruct passwd *getpwent()
Xstruct passwd *getpwuid(uid)
Xint uid;
X
Xint _strccmp(a, b)
Xchar *a,*b;
X
Xstruct passwd *getpwnam(name)
Xchar *name;
X
Xstruct passwd *fgetpwent (f)
XFILE *f;
X
Xint getpw(uid, name)
Xint uid;
Xchar *name;
X
Xint _cmpuid(uidstr, uid)
Xchar *uidstr;
Xint *uid;
X
Xint getpwopt(junk, buf, opt, max)
Xchar *junk;
Xchar *buf;
Xchar opt;
Xint max;
X
Xstruct gecos *getgecos(gecos_field)
Xchar *gecos_field;
X
X.noformend
X.endtopic
X.topic DESCRIPTION
XThe password library provides some useful functions to access the
Xpassword file. In the include file
X.ul
Xpwd.h
Xthere are two structs defined which help to access the password file.
XThe
X.ul
Xstruct passwd
Xis used by the most function, the
X.ul
Xstruct gecos
Xis only used by one function.
X.nf
X.nj
X.in +5
Xstruct passwd {
X char *pw_name;
X char *pw_passwd;
X int pw_uid;
X int pw_gid;
X int pw_prio; /* OS9: Priority of entry */
X char *pw_age;
X char *pw_comment;
X char *pw_gecos;
X char *pw_dir;
X char *pw_xdir; /* OS9: Execution Directory */
X char *pw_shell;
X char *pw_junk; /* everything else... */
X};
X
Xstruct gecos {
X char *fullname;
X char *organization;
X char *office_phone;
X char *home_phone;
X};
X.in -5
X.fill
X.justify
X
XBefore examining the password file you open it with
X.bold
Xsetpwent()
Xand after that close it with
X.bold
Xendpwent()
Xplease don't forget this! If you use the routines on security sensitive
Xparts in your programs then you should set _pw_secure (which should be
Xdeclared as extern) to a non-zero value, otherwise to zero.
X.bold
X_getpw
Xis an internal function which may also be useful if you have a line to parse
Xwhich looks like one in the password file. You have to
Xgive a pointer to a struct passwd where the result will be written to and
Xthe string. If you want to scan through the password file you can use
X.bold
Xgetpwent()
Xwhich returns the next entry in the password file. To determine the
Xpassword entry for a given user-ID or username use the functions
X.bold
Xgetpwuid()
Xand
X.bold
Xgetpwnam()
Xwhich requires each one parameter, getpwuid an integer and getpwnam a
Xstring. The internal function
X.bold
X_strccmp()
Xis like the function strcmp() but ignores cases. The function
X.bold
Xfgetpwent()
Xis like getpwent(), but it works on a given filepointer which should
Xbe opened on a file looking like the password file.
X.bold
XGetwd()
Xcopies the argument name into the username which matches the uid, given
Xas the second parameter.
X.bold
X_compuid()
Xexamines the string uidstr and builds the real uid (as returned by
Xgetuid()) for the user which is stored in *uid.
X
X In the password file exists a field (the last one) for
Xspecial extensions. To extract an extention call
X.bold
Xgetpwopt() .
XIt requires the (complete) last field, a buffer, the option
Xas a character and the maximum size of the buffer.
X
X The field gecos in the struct passwd is a special formated
Xstring to get more informations about the "real" person who owns the
Xaccount. The format of this field is
X.ul
X<fullname> : <organisation> : <office-phone> : <home-phone>
Xand these are the entries in the struct gecos. The function
X.bold
Xgetgecos()
Xrequires a line in the specified format and fills up the struct.
X.endtopic
X.topic CAVEATS
XGetpwent(), getpwuid(), getpwnam(), fgetpwent() and getgecos() returns
Xpointer to static data which will be overwritten by each call.
X.endtopic
X.topic RETURN VALUE
XSetpwent() and endpwent() returns 0 on success, and -1 on failure. _getpw
Xreturns a pointer to struct passwd which is given as a parameter on
Xsuccess, NULL on failure. Getpwent(), getpwuid(), getpwnam() and
Xfgetpwent() return a pointer to struct passwd on success, NULL on
Xfailure. _strccmp() returns the same value as strcmp() but ignores case
Xwhile comparing the strings. Getwd() returns -1 on failure and 0 on
Xsuccess. _cmpuid() returns 0 on success and -1 on failure. getpwopt()
Xreturns 0 on success and -1 on failure. Getgecos returns a pointer to
Xstruct gecos on success or NULL on failure.
X.endtopic
X.topic FILES
X.noform
X/<bootdrive>/SYS/password
X/dd/SYS/password
X.noformend
X.endtopic
X.topic SEE ALSO
X.noform
Xthe group library
Xin the TOP OS9Lib Documentation
X.noformend
X.endtopic
END_OF_FILE
if test 4722 -ne `wc -c <'MAN/Passwd.prf'`; then
echo shar: \"'MAN/Passwd.prf'\" unpacked with wrong size!
fi
# end of 'MAN/Passwd.prf'
fi
if test -f 'popen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'popen.c'\"
else
echo shar: Extracting \"'popen.c'\" \(4762 characters\)
sed "s/^X//" >'popen.c' <<'END_OF_FILE'
X/* ------------------------------------------------------------------- *
X |
X | OS9Lib: popen(), xpopen(), pclose()
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 <modes.h>
X#include <strings.h>
X#include <errno.h>
X
Xextern FILE *fdopen();
X
Xextern char **environ;
Xextern int os9forkc();
X
Xextern char *findmod(), *getenv(), *info_str();
X
Xstatic char cmd_name[256];
X
Xstruct pid_stat {
X int used;
X int pid;
X int status;
X} ;
X
Xstatic int pids[_NFILE] = { 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0 };
X
Xint _popen_secure = 0;
X
X/*
X * c h e c k _ s h e l l
X *
X * check for valid shells
X */
Xstatic int check_shell()
X{
X char *shell, *cp, *cp2, *cp3, val_shell[200];
X
X errno = E_FNA;
X
X if ((shell = getenv("SHELL")) == NULL)
X return(0);
X
X if (info_str("valid.shells", val_shell, sizeof(val_shell)) == NULL)
X strcpy(val_shell, "shell,sh,csh");
X
X for (cp = val_shell; cp != NULL && *cp != '\0'; ) {
X cp2 = cp;
X if ((cp = index(cp, ',')) != NULL)
X *cp++ = '\0';
X
X while (*cp2 == ' ')
X cp2++;
X if ((cp3 = index(cp2, ' ')) != NULL)
X *cp3 = '\0';
X
X if (!strcmp(shell, cp2))
X return(1);
X }
X
X return(0);
X}
X
X/*
X * p o p e n
X */
XFILE *popen(name, mode)
X register char *name, *mode;
X{
X register int fd, fd2, fdsav, pid;
X static char *argv[] = {NULL, NULL, NULL };
X static char cmd[200];
X static char cmd_path[200];
X register char *cp;
X
X if (_popen_secure)
X if (!check_shell())
X return(NULL);
X
X cp = name;
X while (*cp == ' ')
X cp++;
X strcpy(cmd_path, cp);
X
X if (cp = index(cmd_path, ' '))
X *cp++ = '\0';
X
X strcpy(cmd, "ex ");
X strcat(cmd, findmod(cmd_path, cmd_path));
X if (cp) {
X strcat(cmd, " ");
X strcat(cmd, cp);
X }
X
X argv[1] = cmd;
X
X/*
X * mode kann "r" (stdout) oder "w" (stdin) sein
X */
X switch(mode[0]) {
X case 'w':
X fd = 0;
X break;
X
X case 'r':
X fd = 1;
X break;
X }
X
X if (fd == 1)
X fflush(stdout);
X
X fdsav = dup(fd);
X close(fd);
X
X creat("/pipe", S_IWRITE+S_IREAD);
X argv[0] = findmod("shell", "SYSTEM.SHELL");
X pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3);
X
X fd2 = dup(fd);
X close(fd);
X dup(fdsav);
X close(fdsav);
X
X if (pid > 0) {
X pids[fd2] = pid;
X return(fdopen(fd2, mode));
X }
X else {
X close(fd2);
X return(NULL);
X }
X}
X
X
X/*
X * x p o p e n
X */
XFILE *xpopen(name, mode)
X register char *name, *mode;
X{
X register int fd, fd2, fdsav, pid;
X char **argv;
X
X if (_popen_secure)
X if (!check_shell())
X return(NULL);
X
X strcpy(cmd_name, name);
X
X if (getargs(cmd_name, &argv) == -1)
X return(NULL);
X
X/*
X * mode kann "r" (stdout) oder "w" (stdin) sein
X */
X switch(mode[0]) {
X case 'w':
X fd = 0;
X break;
X
X case 'r':
X fd = 1;
X break;
X }
X
X if (fd == 1 && fileno(stdout) == 1)
X fflush(stdout);
X
X fdsav = dup(fd);
X close(fd);
X
X creat("/pipe", S_IWRITE+S_IREAD);
X pid = os9exec(os9forkc, findmod(argv[0], argv[0]), argv, environ, 0, 0, 3);
X
X free(argv);
X
X fd2 = dup(fd);
X close(fd);
X dup(fdsav);
X close(fdsav);
X
X if (pid > 0) {
X pids[fd2] = pid;
X return(fdopen(fd2, mode));
X }
X else {
X close(fd2);
X return(NULL);
X }
X}
X
X/*
X * p c l o s e
X */
Xunsigned int pclose(fp)
X register FILE *fp;
X{
X unsigned int status;
X register int pid;
X register int fd, i;
X
X fd = fileno(fp);
X
X if (pids[fd] == 0)
X return(-1);
X fflush(fp);
X fclose(fp);
X
X while ((pid = wait(&status)) != -1)
X if (pid == pids[fd])
X break;
X else
X for (i = 0; i < _NFILE; i++)
X if (pids[i] == pid) {
X pids[i] = 0;
X break;
X }
X
X if (pid == -1)
X status = -1;
X
X pids[fd] = 0;
X return(status);
X}
X
X
END_OF_FILE
if test 4762 -ne `wc -c <'popen.c'`; then
echo shar: \"'popen.c'\" unpacked with wrong size!
fi
# end of 'popen.c'
fi
if test -f 'signal.a' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'signal.a'\"
else
echo shar: Extracting \"'signal.a'\" \(4849 characters\)
sed "s/^X//" >'signal.a' <<'END_OF_FILE'
X* Author: Reimer Mellin
X* Date: 03/14/87
X* Version: 1.3
X*
X*
X* Revisions:
X* 1.2 _sigini -> _siginit() (weo)
X* 1.3 _siginit() called by signal, if not installed yet
X*
X*
X*
X* Description:
X* The following UNIX (tm) functions are emulated:
X*
X* - _siginit()
X*
X* to initialize (no more required since 1.3 (weo))
X*
X*
X* - int (signal(signum, sig_handler)) ()
X* int signum;
X* int (sig_handler()) ();
X*
X* as the signal() function of UNIX (tm)
X*
X*
X* - _icptexce(excp_handler)
X* (void) excp_handler();
X*
X* to install the exeception handler function excp_handler()
X*
X* (void) excp_handler(excp_num, reg_frame)
X* int exep_num;
X* registerpack reg_frame;
X*
X*
X
X* Exception Vector address definitions
X org 0
XT_ColdSP: do.l 1 (0) reset initial SSP
XT_ColdPC: do.l 1 (1) reset initial PC
XT_BusErr: do.l 1 (2) bus error
XT_AddErr: do.l 1 (3) address error
XT_IllIns: do.l 1 (4) illegal instruction
XT_ZerDiv: do.l 1 (5) zero divide
XT_CHK: do.l 1 (6) CHK instruction
XT_TRAPV: do.l 1 (7) TRAPV instruction
XT_Priv: do.l 1 (8) privelage violation
XT_Trace: do.l 1 (9) trace
XT_1010: do.l 1 (10) line 1010 emulator
XT_1111: do.l 1 (11) line 1111 emulator
X do.l 3 (12-14) reserved
XT_UnIRQ: do.l 1 (15) unitialized interrupt vector
X do.l 8 (16-23) reserved
XT_SpurIO: do.l 1 (24) spurious interrupt
XT_AutIRQ: do.l 7 (25-31) level 1-7 interrupt autovectors
XT_TRAP: do.l 16 (32-47) TRAP instruction vectors
XT_FPUnordC: do.l 1 (48) FPCP bra or set on unordered condition
XT_FPInxact: do.l 1 (49) FPCP inexact result
XT_FPDivZer: do.l 1 (50) FPCP divide by zero
XT_FPUndrFl: do.l 1 (51) FPCP underflow
XT_FPOprErr: do.l 1 (52) FPCP operand error
XT_FPOverFl: do.l 1 (53) FPCP overflow
XT_FPNotNum: do.l 1 (54) FPCP signaling not a number
X do.l 9 (55-63) reserved
XT_VctIRQ: do.l 192 vectored interrupt vectors
XT_End: equ .
X
X psect signals_a,0,0,0,0,0
X
XSIG_NUM equ 10
X
X vsect
X_siglist ds.w (SIG_NUM*3)+1
X_exerout ds.l 1
X_isinit dc.b 0
X ends
X
X_siginit:
X tst.b _isinit(a6)
X bne.s _siginit99
X
X movem.l d0/d1/a0,-(a7)
X
X lea _siglist(a6),a0 ; Adresse der Signal-Tabelle
X moveq #1,d0 ; Merker fuer ungenutzt
X moveq #SIG_NUM-1,d1 ; Anzahl der Signale
X
Xsig01
X move.w d0,(a0)+ ; markieren als unbenutzt
X clr.l (a0)+ ; Adresse der Routine auf Null
X dbra d1,sig01
X
X clr.w (a0) ; Ende der Tabelle
X lea _sighand(pc),a0 ; die Intercept-Routine ...
X OS9 F$Icpt ; installieren
X
X st _isinit(a6) ; jetzt initialisiert
X
X movem.l (a7)+,d0/d1/a0
X
X_siginit99
X rts
X
Xsignal:
X movem.l a0-a1/d2-d3,-(a7) ; Register retten
X
X tst.b _isinit(a6) ; initialisiert?
X bne.s sig02 ; ja!
X bsr.s _siginit
X
Xsig02
X move.w d0,d3 ; kopiere Signal
X andi.l #$fffe,d3 ; maskiere Bit 1-15
X beq.s sig05
X
X moveq.l #1,d3 ; Default-Aktion ist 1
X bsr.s _siglook ; Signal-Nummer in Tabelle suchen
X tst.l d2 ; Tabelle voll?
X beq.s sig05 ; ja!
X
X tst.l d1 ; Default Aktion verlangt?
X beq.s sig03 ; ja, der Eintrag kann geloescht werden
X
Xsig04
X move.w d0,(a0)+ ; Signal-Nummer
X move.l (a0),d3 ; vorherige Adresse
X move.l d1,(a0)+ ; neue Adresse des Handlers
X
Xsig05
X move.l d3,d0 ; Return-Wert ist die alte Adresse
X movem.l (a7)+,a0-a1/d2-d3 ; Register restaurieren
X rts
X
Xsig03
X move.l 2(a0),d3 ; alte Adresse
X movea.l a0,a1
X addq.l #6,a1
X
Xsig06
X move.w #1,(a0) ; altes Signal loeschen
X move.l #0,2(a0) ; auch alte Adresse loeschen
X tst.w (a1) ; am Ende der Tabelle?
X beq.s sig05 ; ja!
X
X move.w (a1)+,(a0)+ ; Signal-Nummer eintragen
X move.l (a1)+,(a0)+ ; dazugehoerige Handler-Adresse
X bra.s sig06
X
X_siglook
X lea _siglist(a6),a0 ; Signal-Tabelle
X
Xsig07
X move.w (a0),d2 Signal-Nummer
X cmp.w d0,d2 ; die gesuchte?
X beq.s sig08 ; ja!
X
X cmpi.w #1,d2 ; freier Eintrag?
X beq.s sig08 ; ja!
X
X tst.w d2 ; Tabellenende?
X beq.s sig08 ; ja!
X
X addq.l #6,a0 ; naechster Eintrag
X bra.s sig07
X
Xsig08
X ext.l d2
X rts
X
X_sighand
X movem.l a0-a1/d2,-(a7) ; Register retten
X move.l d1,d0 ; Signalnummer ist in d1
X bsr.s _siglook ; Eintrag vorhanden?
X subq.l #1,d2
X ble.s sig09 ; keinen Eintrag gefunden, exit()!
X
X addq.l #2,a0 ; Adresse der Adresse
X
X cmpi.l #1,(a0) ; Signal ignorieren?
X beq.s sig10 ; ja!
X
X movea (a0),a0 ; zu dieser Adresse springen
X jsr (a0)
X
Xsig10
X movem.l (a7)+,a0-a1/d2 Register restaurieren
X OS9 F$RTE ; Ende der Intercept-Routine
X
Xsig09
X move.l d0,d1 ; Signal-Nummer fuer exit
X OS9 F$Exit
X bra.s sig09 ; ???
X
X_exetab
X dc.w T_BusErr,_exehand-*-4 ; Tabelle fuer Exceptions
X dc.w T_AddErr,_exehand-*-4
X dc.w T_IllIns,_exehand-*-4
X dc.w T_ZerDiv,_exehand-*-4
X dc.w T_CHK,_exehand-*-4
X dc.w T_TRAPV,_exehand-*-4
X dc.w T_Priv,_exehand-*-4
X dc.w T_1010,_exehand-*-4
X dc.w T_1111,_exehand-*-4
X dc.w -1
X
X_icptexep:
X move.l d0,_exerout(a6) ; Adresse der Routine
X lea _exetab(pc),a1 ; Trap-Tabelle
X movea.l #0,a0 ; a0 = 0 fuer Default-Stack
X OS9 F$STrap ; Trap installieren
X rts
X
X_exehand
X move.w d7,d0
X ext.l d0
X move.l a5,d1 ; Registerframe
X movea _exerout(a6),a0 ; Handler-Routine
X jsr (a0) ; aufrufen
X rts
X
X ends
X end
END_OF_FILE
if test 4849 -ne `wc -c <'signal.a'`; then
echo shar: \"'signal.a'\" unpacked with wrong size!
fi
# end of 'signal.a'
fi
echo shar: End of archive 3 \(of 5\).
cp /dev/null ark3isdone
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? |