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