Newsgroups: alt.sources
From: ken@bitsko.slc.ut.us (Ken MacLeod)
Subject: Unidel 1.0, a Citadel-style news/mail reader and BBS, part 09 of 09
Message-ID: <1992May3.013037.19038@bitsko.slc.ut.us>
Date: Sun, 3 May 1992 01:30:37 GMT

Submitted-by: ken@bitsko.slc.ut.us
Archive-name: unidel-1.0/part09

---- Cut Here and unpack ----
#!/bin/sh
# This is part 09 of unidel-1.0
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= misc/Makefile ==============
echo "x - extracting misc/Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/Makefile &&
XCFLAGS=-g -I../src
X
XPROGS=AutoVal DoStat NewUser NewUser2 SetUp adm-rmail buseradd getpass \
X	new-mail newUser unilogin
X
Xall:
X	@echo "Make each program by hand."
X
X#install: $(PROGS)
X#	cp $(PROGS) ../bin
X
XLGNOBJS=unilogin.o getpass.o
Xunilogin: $(LGNOBJS)
X	$(CC) $(CFLAGS) $(LGNOBJS) ../src/fgetmfs.o -o unilogin
X
X#PWDOBS=unipasswd.o getpass.o
X#	$(CC) $(CFLAGS) $(LGNOBJS) ../src/fgetmfs.o -o unipasswd
X
Xclean:
X	rm -f *~ *.o
X
Xclobber: clean
X	rm -f ${PROGS}
SHAR_EOF
$TOUCH -am 0502180392 misc/Makefile &&
chmod 0644 misc/Makefile ||
echo "restore of misc/Makefile failed"
set `wc -c misc/Makefile`;Wc_c=$1
if test "$Wc_c" != "455"; then
	echo original size 455, current size $Wc_c
fi
# ============= misc/NewUser.sh ==============
echo "x - extracting misc/NewUser.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/NewUser.sh &&
X#
X#  NewUser  --  auto registration for new users
X#
X
XUNIDIR=/home/rspdev/ken/play/unidel
XLIBDIR=$UNIDIR/lib
XBINDIR=$UNIDIR/bin
XDOCDIR=$UNIDIR/doc
XHOMEDIRS=$UNIDIR/usr
XpasswdFile=/home/rspdev/ken/play/unidel/lib/passwd
XminPasswd=301
Xgid=102
XadminAddress=ken
X
Xecho
X
Xif [ -f $DOCDIR/blurb.doc ]
Xthen
X	more $DOCDIR/blurb.doc
Xfi
X
Xecho "\n\nWould you like to register? ([y]/n) \c"
Xread ans
Xif [ "$ans" = "n" ] 
Xthen
X  echo "We're sorry to have wasted your time, we'll log you out now."
X  exit 1
Xfi
X
Xans=n
Xwhile [ "$ans" = "n" ]
Xdo
X  while [ "$ans" = "n" ]
X  do
X    echo "
XEnter your login name or handle.  This is the name you will use when you log
Xinto this system.  It is also the name the system knows you by, and your
Xmailing address on this system.  For best results, do not use periods,
Xspaces, colons or other special characters.  There is an 8 character limit.
XYou can not change this name, and it must be unique among all names on this
Xsystem.  You will have as many chances as required to pick a unique name.
XLogin name:"
X    read name
X    name=`echo "$name" | /usr/bin/tr -d ":"`
X    tName=`echo "$name" | /usr/bin/tr -d ".@$#\'\"\\/"`
X    loginName=`echo "$tName" | /usr/bin/tr " [A-Z]" "_[a-z]" | cut -c1-8`
X    if /bin/grep "^$loginName:" $passwdFile >/dev/null
X    then
X      echo "We already have someone by that name, try a different spelling."
X      ans=n
X    else
X      ans=y
X    fi
X  done
X  echo "
XEnter your full name.  This is the name that other users around the world
Xwill see on messages that you write.  If you are going to be using USENET,
Xthe world wide network, it is recomended that you use your REAL name.  This
Xname can be changed at any time.
XFull name:"
X  read name
X  fullName=`echo "$name" | /usr/bin/tr -d ":"`
X  echo "City, State, Zip:"
X  read city
X  echo "Computer type? (ex. Mac II, Compaq 386, Cray X/MP, AT Clone, etc.)"
X  read computer
X  echo
X#  name=`echo "$name" | $BINDIR/UpLow`
X#  city=`echo "$city" | $BINDIR/UpLow`
X  echo "Name:      $fullName"
X  echo "City:      $city"
X  echo "Computer:  $computer"
X  echo
X  echo "Is this correct? ([y]/n) \c"
X  read ans
Xdone
Xecho "Creating user information files..."
XpasswdLine="$loginName:,..:$minPasswd:$gid:$fullName:$HOMEDIRS/$loginName:$BINDIR/unidel"
Xset `echo "$passwdLine" | $BINDIR/AutoVal`
XuserNumber=$1
Xshift
XerrorMessage="$*"
X
Xif [ "$userNumber" = "0" ]
Xthen
X  echo "Oops, we've had an error trying to create a log-in for you, we'll save"
X  echo "this information for later, try logging in a few days and we should have"
X  echo "everything straightened out."
X  echo
X  echo "When you log in a few days your login is '$loginName'"
X  echo
X  (
X    echo "\n******   NOT REGISTERED!!  ******"
X	echo "#ERROR $errorMessage"
X    echo "#N $name"
X    echo "#C $city"
X	echo "#M $computer"
X    echo "#D `date`"
X    echo "#p $passwdLine"
X  ) | tee -a $LIBDIR/loginErrs | /bin/mail $adminAddress
X  exit 1
Xfi
XhomeDir="$HOMEDIRS/$loginName"
Xecho "Setting up your account..."
Xcp $LIBDIR/defaultDeliver $homeDir/.deliver
Xmkdir $homeDir/.mail
Xtouch $homeDir/.mail/history.pag $homeDir/.mail/sys
Xecho "mail 0000000000 00001 y" >$homeDir/.mail/active
Xchmod 444 $homeDir/.deliver $homeDir/.mail/history.pag $homeDir/.mail/sys
Xchmod 660 $homeDir/.mail/active
Xchmod 775 $homeDir/.mail
X#
X# Uncomment this if you have chown runnable by someone other than root
X#
X# chown $loginName $homeDir/.deliver $homeDir/.mail $homeDir/.mail/active $homeDir/.mail/history.pag $homeDir/.mail/sys
X(
X  echo "\n#N $name"
X  echo "#C $city"
X  echo "#M $computer"
X  echo "#U $userNumber"
X  echo "#D `date`"
X  echo "#p $passwdLine"
X) | tee -a $LIBDIR/users | /bin/mail $adminAddress
Xecho
Xecho
Xecho "IMPORTANT:  Your login name is:"
Xecho
Xecho "      $loginName"
Xecho
Xecho "NOTE that it is all lower case and spaces are '_'"
Xecho "
X                          *** IMPORTANT ***
X
XPlease log in now, you will be asked for your login name.  Type in your login
Xname from above followed by a RETURN.  The system will then tell you that
Xyour password has expired and ask you for a new one.  You must enter the same
Xpassword (your new one) twice to convince the system that you really know
Xwhat your new password is.  Read these instructions carefully to avoid being
Xhung up on.
X                   ***YOU WILL ONLY GET 3 CHANCES***"
XSHELL=/bin/sh
Xexport SHELL
Xunset PAGER EDITOR VISUAL TERM
Xexec unilogin
Xexit 0
SHAR_EOF
$TOUCH -am 0502134492 misc/NewUser.sh &&
chmod 0644 misc/NewUser.sh ||
echo "restore of misc/NewUser.sh failed"
set `wc -c misc/NewUser.sh`;Wc_c=$1
if test "$Wc_c" != "4343"; then
	echo original size 4343, current size $Wc_c
fi
# ============= misc/NewUser2.sh ==============
echo "x - extracting misc/NewUser2.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/NewUser2.sh &&
X#
X#  NewUser  --  auto registration for new users
X#
X
XUNIDIR=/usr/local/lib/unidel
XLIBDIR=$UNIDIR/lib
XBINDIR=$UNIDIR/bin
XDOCDIR=$UNIDIR/doc
XSECUREDIR=$UNIDIR/secure
XHOMEDIRS=/var/spool/bbshome
Xgid=101
XadminAddress=postmaster
XpasswdFile=/etc/passwd
X
Xtrap "" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Xecho
X
Xif [ -f $DOCDIR/blurb.doc ]
Xthen
X	more $DOCDIR/blurb.doc
Xfi
X
Xans=n
Xwhile [ "$ans" = "n" ]
Xdo
X  echo "
XEnter your full name.  This is the name that other users around the world
Xwill see on messages that you write.  If you are going to be using USENET,
Xthe world wide network, it is recommended that you use your REAL name.  This
Xname can be changed at any time.
XFull name:"
X  read name
X  fullName=`echo "$name" | /usr/bin/tr -d ":"`
X  while [ "$ans" = "n" ]
X  do
X    echo "
XEnter your login name or handle.  This is the name you will use when you log
Xinto this system.  It is also the name the system knows you by, and your
Xmailing address on this system.  For best results, do not use periods,
Xspaces, colons or other special characters.  There is an 8 character limit.
XYou can not change this name, and it must be unique among all names on this
Xsystem.  You will have as many chances as required to pick a unique name.
XLogin name:"
X    read name
X    name=`echo "$name" | /usr/bin/tr -d ":"`
X    tName=`echo "$name" | /usr/bin/tr -d ".@$#\'\"\\/"`
X    loginName=`echo "$tName" | /usr/bin/tr " [A-Z]" "_[a-z]" | cut -c1-8`
X    if /bin/grep "^$loginName:" $passwdFile >/dev/null
X    then
X      echo "We already have someone by that name, try a different spelling."
X      ans=n
X    else
X      ans=y
X    fi
X  done
X  echo "City, State, Zip:"
X  read city
X  echo "Computer type? (ex. Mac II, Compaq 386, Cray X/MP, AT Clone, etc.)"
X  read computer
X  echo
X#  name=`echo "$name" | $BINDIR/UpLow`
X#  city=`echo "$city" | $BINDIR/UpLow`
X  echo "Name:      $fullName"
X  echo "Login:     $loginName"
X  echo "City:      $city"
X  echo "Computer:  $computer"
X  echo
X  echo "Is this correct? ([y]/n) \c"
X  read ans
Xdone
Xecho "Creating user information files..."
X
X$UNIDIR/buseradd $loginName "$fullName"
X
XSHELL=/bin/sh
Xexport SHELL
Xunset PAGER EDITOR VISUAL TERM
X
X# We won't tell them it's not our fault :-)
Xecho "\nAnd Once More Just For Jokes, \c"
Xexec login $loginName
X
X# in case login wasn't found.
Xexit 0
SHAR_EOF
$TOUCH -am 0502135092 misc/NewUser2.sh &&
chmod 0644 misc/NewUser2.sh ||
echo "restore of misc/NewUser2.sh failed"
set `wc -c misc/NewUser2.sh`;Wc_c=$1
if test "$Wc_c" != "2291"; then
	echo original size 2291, current size $Wc_c
fi
# ============= misc/SetUp.sh ==============
echo "x - extracting misc/SetUp.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/SetUp.sh &&
X#! /bin/sh
X
XRECALLDIR=/home/rspdev/ken/play/unidel/usr
XHOMEDIR=$1
XHOME=$RECALLDIR/$HOMEDIR
X
Xecho "`date`" >$HOME/.lastTime
Xecho "Terminal: $TERM" >>$HOME/.unidelrc
Xecho "FloorMode: Yes" >>$HOME/.unidelrc
Xecho "Editor: Edit" >>$HOME/.unidelrc
X
X#
X# Uncomment this if AutoVal suid root and using /etc/passwd
X#
X#chown $1 $HOME/.lastTime $HOME/.unidelrc
SHAR_EOF
$TOUCH -am 0502134492 misc/SetUp.sh &&
chmod 0644 misc/SetUp.sh ||
echo "restore of misc/SetUp.sh failed"
set `wc -c misc/SetUp.sh`;Wc_c=$1
if test "$Wc_c" != "349"; then
	echo original size 349, current size $Wc_c
fi
# ============= misc/adm-rmail.c ==============
echo "x - extracting misc/adm-rmail.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/adm-rmail.c &&
X/*
X * NAME
X *     adm-rmail -- record size of files mailed for accounting
X *
X * DESCRIPTION
X *     I use this program to record the size of mail received from
X *     other sites for accounting.  I pay long distance to get quick
X *     mail through UUNET.
X */
X
X#include <stdio.h>
X#include <sys/stat.h>
X
X/*
X * _fudgeFactor is an approximation of the time/bytes used up in
X * transferring the control file and dead time between files.  It is
X * added to the raw file size.  It was calculated
X *     8 seconds * 150 bytes/second
X */
X#define _fudgeFactor 1200
X
Xchar *logFileName = "/usr/local/lib/unidel/lib/log-rmail";
Xchar *realRMail = "/usr/bin/rmail";
X
Xmain (int argc, char **argv, char **envp)
X{
X  extern int errno;
X  FILE *logFile;
X  struct stat fileStat;
X  int ii;
X  char *uuName, *getenv();
X
X  if ((argc > 1) &&(logFile = fopen (logFileName, "a")) != (FILE *) NULL) {
X    if (fstat (0, &fileStat) == -1) {
X      (void) fprintf (logFile, "# %s -- Could not stat input file, errno == %d\n", argv[1], errno);
X    } else if (fileStat.st_mode & S_IFREG) {
X      uuName = getenv ("UU_MACHINE");
X      if (uuName == (char *) NULL)
X	uuName = "unknown";
X      for (ii = 1; ii < argc; ii ++) {
X	(void) fprintf (logFile, "%ld\t%s\t%s\n",
X			(fileStat.st_size + _fudgeFactor) / (argc - 1),
X			argv[ii], uuName);
X      }
X    } else {
X      (void) fprintf (logFile, "# %s -- Not a regular file, st_mode = 0x%4.4x\n",
X		      argv[1], fileStat.st_mode);
X    }
X  }
X  fclose (logFile);
X  (void) execve (realRMail, argv, envp);
X  /* Should not return */
X  return (1);
X}
SHAR_EOF
$TOUCH -am 0502134792 misc/adm-rmail.c &&
chmod 0644 misc/adm-rmail.c ||
echo "restore of misc/adm-rmail.c failed"
set `wc -c misc/adm-rmail.c`;Wc_c=$1
if test "$Wc_c" != "1555"; then
	echo original size 1555, current size $Wc_c
fi
# ============= misc/README ==============
echo "x - extracting misc/README (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/README &&
XThese files and programs are here for your perusal and possible use.
XOtherwise, they are old, probably buggy and incomplete, non-portable,
Xand definitely not documented well.
X
XNewUser2.sh is the program I place in 'guest's $HOME/.profile to add
Xnew users.
SHAR_EOF
$TOUCH -am 0502135192 misc/README &&
chmod 0644 misc/README ||
echo "restore of misc/README failed"
set `wc -c misc/README`;Wc_c=$1
if test "$Wc_c" != "256"; then
	echo original size 256, current size $Wc_c
fi
# ============= misc/buseradd.c ==============
echo "x - extracting misc/buseradd.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/buseradd.c &&
X#include <stdio.h>
X#include <unistd.h>
X#include <string.h>
X
X#define _maxNameLen 8
X#define _maxFullNameLen 40
X
Xchar baseDir[] = "/var/spool/bbshome/";
X
Xmain (argc, argv, envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
X	char homeDir[sizeof(baseDir)+_maxNameLen+1];
X	int status;
X
X	if (argc != 3) {
X		(void) fprintf (stderr, "usage: %s login fullName\n", argv[0]);
X		exit (2);
X	}
X	if (strlen(argv[1]) > (size_t) _maxNameLen) {
X		(void) fprintf (stderr, "%s: user name too long.\n", argv[0]);
X		exit (2);
X	}
X	if (strlen(argv[2]) > (size_t) _maxFullNameLen) {
X		(void) fprintf (stderr, "%s: full name too long.\n", argv[0]);
X		exit (2);
X	}
X
X	(void) strcpy (homeDir, baseDir);
X	(void) strcat (homeDir, argv[1]);
X
X	setuid(0);
X	if (fork() == 0) {
X		execl ("/usr/sbin/useradd", "-gbbs", "-d", homeDir, "-s/usr/local/bin/unidel", "-c", argv[2], "-m", "-k/usr/local/lib/unidel/skel", argv[1], (char *)0);
X		exit (1);
X	}
X	wait(&status);
X	execl ("/usr/bin/passwd", "-d", argv[1], (char *)0);
X}
SHAR_EOF
$TOUCH -am 0502134492 misc/buseradd.c &&
chmod 0644 misc/buseradd.c ||
echo "restore of misc/buseradd.c failed"
set `wc -c misc/buseradd.c`;Wc_c=$1
if test "$Wc_c" != "976"; then
	echo original size 976, current size $Wc_c
fi
# ============= misc/defaultDeliver ==============
echo "x - extracting misc/defaultDeliver (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/defaultDeliver &&
Xcat $HEADER $BODY | /usr/lib/citadel/dlvr/fdeliver -u $1 2>/dev/null
Xecho "DROP"
SHAR_EOF
$TOUCH -am 0502134492 misc/defaultDeliver &&
chmod 0644 misc/defaultDeliver ||
echo "restore of misc/defaultDeliver failed"
set `wc -c misc/defaultDeliver`;Wc_c=$1
if test "$Wc_c" != "81"; then
	echo original size 81, current size $Wc_c
fi
# ============= misc/getpass.c ==============
echo "x - extracting misc/getpass.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/getpass.c &&
X/*
X * Copyright (c) 1988 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)getpass.c	based on 5.3 (Berkeley) 9/22/88";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/ioctl.h>
X#include <sys/signal.h>
X#include <stdio.h>
X
Xchar *
Xgetpass(prompt)
X	char *prompt;
X{
X	struct sgttyb ttyb;
X	register int ch;
X	register char *p;
X	FILE *fp, *outfp;
X	long omask;
X	int svflagval;
X#define	PASSWD_LEN	128
X	static char buf[PASSWD_LEN + 1];
X
X	/*
X	 * read and write to /dev/tty if possible; else read from
X	 * stdin and write to stderr.
X	 */
X	if ((outfp = fp = fopen("/dev/tty", "w+")) == NULL) {
X		outfp = stderr;
X		fp = stdin;
X	}
X
X	(void)ioctl(fileno(fp), TIOCGETP, &ttyb);
X	svflagval = ttyb.sg_flags;
X	ttyb.sg_flags &= ~ECHO;
X	omask = sigblock(sigmask(SIGINT));
X	(void)ioctl(fileno(fp), TIOCSETP, &ttyb);
X
X	fputs(prompt, outfp);
X	rewind(outfp);			/* implied flush */
X	for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
X		if (p < buf + PASSWD_LEN)
X			*p++ = ch;
X	*p = '\0';
X	(void)write(fileno(outfp), "\n", 1);
X
X	ttyb.sg_flags = svflagval;
X	(void)ioctl(fileno(fp), TIOCSETP, &ttyb);
X	(void)sigsetmask(omask);
X	if (fp != stdin)
X		(void)fclose(fp);
X	return(buf);
X}
X
SHAR_EOF
$TOUCH -am 0502134492 misc/getpass.c &&
chmod 0644 misc/getpass.c ||
echo "restore of misc/getpass.c failed"
set `wc -c misc/getpass.c`;Wc_c=$1
if test "$Wc_c" != "1973"; then
	echo original size 1973, current size $Wc_c
fi
# ============= misc/new-mail.sh ==============
echo "x - extracting misc/new-mail.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/new-mail.sh &&
X#!/bin/sh
X#
X# NAME
X#    new-mail  --  start up mail processing for a user
X#
X# SYNOPSIS
X#    new-mail userName
X#
X# DESCRIPTION
X#    I use this because I haven't fixed SetUp.sh to automatically create
X#    a link for the new user's mail file to forward mail to 'place'.
X#
X
XuserName=$1
XspoolDir=/var/mail
XbbsHome=/var/spool/bbshome
Xplace=/usr/local/bin/place
X
X# lnName is the name of the mail file used to link to this users file
XlnName=mickey
X
Xif [ "0$userName" = "0" ]
Xthen
X  echo "usage: $0 userName"
X  exit 1
Xfi
X
Xegrep "^$userName:" /etc/passwd >/dev/null || {
X  echo "$0: No such user '$userName'"
X  exit 1
X}
X
Xcd $spoolDir
X
X[ -f $userName.bak ] && {
X  echo "$0: Backup file $spoolDir/$userName.bak already exists."
X  exit 1
X}
X
Xcp $userName $userName.bak
X
X[ -f $userName ] || {
X  echo "$0: No such file or not an ordinary file, '$spoolDir/$userName'"
X  exit 1
X}
X
Xmkdir split
Xcd split
X
XLOGNAME=$userName
XHOME=$bbsHome/$userName
Xexport LOGNAME HOME
X
Xcsplit -k - "/^From /" "{98}" <../$userName
X
Xif [ -f x99 ]
Xthen
X  egrep "^From " xx99 >/dev/null && {
X    echo "$0: More than 98 messages in '$spoolDir/$userName'"
X    echo "$0: Messages left in $spoolDir/split"
X    exit 1
X  }
Xfi
X
Xrm xx00
X
Xfor ii in xx??
Xdo
X  $place mail <$ii
Xdone
X
Xrm xx??
Xcd ..
Xrmdir split
Xcd $bbsHome/$userName/mail
Xchown $userName active mail/*
Xchmod 640 active mail/*
X
Xcd $spoolDir
Xln $lnName $userName
SHAR_EOF
$TOUCH -am 0502140692 misc/new-mail.sh &&
chmod 0644 misc/new-mail.sh ||
echo "restore of misc/new-mail.sh failed"
set `wc -c misc/new-mail.sh`;Wc_c=$1
if test "$Wc_c" != "1374"; then
	echo original size 1374, current size $Wc_c
fi
# ============= misc/newUser.c ==============
echo "x - extracting misc/newUser.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/newUser.c &&
X/*----------------------------------------------------------------------------
X * This program will add a user entry to the password file.
X *
X *  Usage: newUser acctName minMum groupName fullName loginDirectory defaultShell defaultAge
X *  Warning: This program is setuid!
X */
X
X#include <stdio.h>
X#include <grp.h>
X#include <pwd.h>
X#include <malloc.h>
X
X/*----------------------------------------------------------------------------
X * Supply version control information.
X */
X
Xstatic char	NEWUSER [] = "@(#) newUser.c 1.1 -- Add a user name to passwd file -- 89/03/18 22:06:04";
X
Xint groupNumber (), userNumber (), setuid (), putpwent ();
Xstruct group *getgrnam (), *theGroup;
Xstruct passwd *getpwent ();
Xvoid endgrent (), endpwent (), setpwent ();
X
Xmain (argc, argv)
X
Xint argc;
Xchar *argv [];
X
X{
X	register uNum, gNum;
X	char passwdDir [80];
X	struct passwd *newEntry;
X	FILE *passwordFile;
X
X	if (argc < 5) {
X		fprintf (stderr, "newUser: usage: user minNumber groupName fullName [logDir [shell] [aging]]\n");
X		exit (1);
X	}
X	if ((gNum = groupNumber (argv [3])) == 0) {
X		fprintf (stderr, "No group found: %s\n", argv [3]);
X		exit (1);
X	}
X	if ((uNum = userNumber (argv [1], atoi (argv [2]))) == 0) {
X		fprintf (stderr, "User name: %s is in use.\n", argv [1]);
X		exit (1);
X	}
X	sprintf (&passwdDir [0], "/usr/acct/%s", argv [1]);
X	newEntry = (struct passwd *) malloc (sizeof (struct passwd));
X	newEntry -> pw_passwd = NULL;
X	newEntry -> pw_comment = NULL;
X	newEntry -> pw_uid = uNum;
X	newEntry -> pw_gid = gNum;
X	newEntry -> pw_dir = &passwdDir [0];
X	newEntry -> pw_shell = "/bin/sh";
X	newEntry -> pw_age = NULL;
X	newEntry -> pw_name = argv [1];
X	newEntry -> pw_gecos = argv [4];
X	if (argc > 5) {
X		newEntry -> pw_dir = argv [5];
X	}
X	if (argc > 6) {
X		newEntry -> pw_shell = argv [6];
X	}
X	if (argc > 7) {
X		newEntry -> pw_age = argv [7];
X	}
X	if (setuid (0) == 0) {
X		if ((passwordFile = fopen ("/etc/passwd", "a+")) != NULL) {
X			if (putpwent (newEntry, passwordFile) == 0) {
X				exit (0);
X			}
X		}
X	}
X}
X 
Xint groupNumber (theName)
X
Xchar *theName;
X
X{
X	if ((theGroup = getgrnam (theName)) != NULL) {
X		endgrent ();
X		return (theGroup -> gr_gid);
X	}
X	endgrent ();
X	return (0);
X}
X
Xint userNumber (theName, lowest)
X
Xchar *theName;
Xint lowest;
X
X{
X	register struct passwd *theEntry;
X	register int theUID;
X
X	theUID = lowest;
X	while ((theEntry = getpwent ()) != NULL) {
X		if (strcmp (theName, theEntry -> pw_name) == 0) {
X			endpwent ();
X			return (0);
X		}
X		if (theEntry -> pw_uid == theUID) {
X			++ theUID;
X			setpwent ();
X		}
X	}
X	endpwent ();
X	return (theUID);
X}
SHAR_EOF
$TOUCH -am 0502134492 misc/newUser.c &&
chmod 0644 misc/newUser.c ||
echo "restore of misc/newUser.c failed"
set `wc -c misc/newUser.c`;Wc_c=$1
if test "$Wc_c" != "2549"; then
	echo original size 2549, current size $Wc_c
fi
# ============= misc/unilogin.c ==============
echo "x - extracting misc/unilogin.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/unilogin.c &&
X/*
X * NAME
X *     unilogin -- Accept a unidel login, using a different passwd file.
X *
X * DESCRIPTION
X *     unilogin will request a user name and password and if they are
X * found in passwd then the login shell is executed.
X */
X
X#include <stdio.h>
X#include <pwd.h>
X#include <string.h>
X#include <malloc.h>
X#include <fgetmfs.h>
X#include <varargs.h>
X
X#define _maxTries 5
X
Xstatic char *passwordFileName = "/home/rspdev/ken/play/unidel/lib/passwd";
Xstatic char *emptyEnviron[] = { (char *) NULL };
X
Xmain (argc, argv, envp)
X     int   argc;
X     char *argv[],
X     *envp[];
X{
X  extern char **environ;
X  struct passwd *pw, *GetPwName();
X  char *userName, *password, *crypted, *crypt(), *pp, *setenv(),
X  *getpass();
X  int tries;
X
X  tries = 0;
X  while (1) {
X    while (1) {
X      if (tries++ == _maxTries)
X	return 0;		/* Too many tries */
X    
X      (void) printf ("Enter your BBS login id: ");
X      fflush (stdout);
X      userName = fgetms (stdin);
X      if (userName == (char *) NULL)
X	return 0;		/* end-of-file */
X      pp = strchr (userName, '\n');
X      if (pp)
X	*pp = '\0';
X
X      pw = GetPwName (passwordFileName, userName);
X      if (pw != (struct passwd *) NULL) {
X	pp = strrchr (pw->pw_passwd, ',');
X	if (pp != (char *) NULL)
X	  *pp = '\0';
X	if (*pw->pw_passwd == '\0') {
X	  (void) printf ("Your password has expired.\n");
X	  password = "";
X	  break;
X	}
X      }
X
X      password = getpass ("Enter your password: ");
X
X      if (pw != (struct passwd *) NULL)
X	break;
X      
X      printf ("Login incorrect.\n");
X    }
X
X    if (*password == '\0' && *pw->pw_passwd == '\0')
X      break;
X
X    crypted = crypt (password, pw->pw_passwd);
X
X    if (strcmp (crypted, pw->pw_passwd) == 0)
X      break;
X
X    printf ("Login incorrect.\n");
X  }
X
X  if (chdir (pw->pw_dir) < 0) {
X    (void) printf ("User %s: can't change directory to %s.\n",
X		   pw->pw_name, pw->pw_dir);
X    return (0);
X  }
X
X  environ = emptyEnviron;
X  (void)setenv("LOGNAME", pw->pw_name, 1);
X  (void)setenv("HOME", pw->pw_dir, 1);
X  (void)setenv("SHELL", "/bin/sh", 1);
X  (void)setenv("USER", pw->pw_name, 1);
X  (void)setenv("PATH", "/bin:/usr/bin", 0);
X
X  pp = strrchr (pw->pw_shell, '/');
X  if (pp == (char *) NULL)
X    pp = pw->pw_shell;
X  else
X    pp ++;
X
X  (void) execl (pw->pw_shell, pp, (char *) 0);
X
X  (void) printf ("User %s: can't exec shell.\n", pw->pw_name);
X  return (0);
X}
X
Xstruct passwd *
XGetPwName (fileName, name)
X     char *fileName, *name;
X{
X  static struct passwd pw;
X  static int firstTime = 1;
X  FILE *file;
X  char *pwLine, *pp, *uidStr, *gidStr;
X
X  if (!firstTime)
X    free (pw.pw_name);
X  else
X    firstTime = 0;
X  
X  file = fopen (fileName, "r");
X  if (file == (FILE *) NULL)
X    return ((struct passwd *) NULL);
X  
X  while ((pwLine = fgetms (file)) != (char *) NULL) {
X    pp = strchr (pwLine, '\n');
X    if (pp)
X      *pp = '\0';
X    (void) splitl (pwLine, ":", &pw.pw_name, &pw.pw_passwd, &uidStr,
X		   &gidStr, &pw.pw_gecos, &pw.pw_dir, &pw.pw_shell,
X		   (char *) NULL);
X    if (strcmp (name, pw.pw_name) == 0) {
X      (void) fclose (file);
X      
X      pw.pw_uid = atoi (uidStr);
X      pw.pw_gid = atoi (gidStr);
X#ifdef BSD
X      pw.pw_quota = 0;
X#else
X      pw.pw_age = (char *) NULL;
X#endif
X      pw.pw_comment = (char *) NULL;
X      
X      return (&pw);
X    }
X
X    free (pwLine);
X  }
X
X  (void) fclose (file);
X  
X  return ((struct passwd *) NULL);
X}
X
Xint
X/*splitl (string, delim, arg0, ..., argn, (char *) 0)*/
Xsplitl (va_alist)
Xva_dcl
X
X{
X  register char *ss, *dd, *delim;
X  register int nn, pastArgn;
X  char *string, **arg;
X  va_list pvar;
X
X
X  va_start (pvar);
X  
X  ss = string = va_arg (pvar, char *);
X  delim = va_arg (pvar, char *);
X
X  pastArgn = 0;
X  nn = 0;
X  while (*ss != '\0') {
X    if (!pastArgn && ((arg = va_arg (pvar, char **)) != (char **) 0))
X      *arg = ss;
X    pastArgn = arg == (char **)0;
X    nn ++;
X    
X    /*
X     * Scan for the next delimiter in string (ss)
X     */
X    for (; *ss != '\0'; ss ++) {
X      /* Scan for "this" character (*ss) in delim (dd) */
X      dd = delim;
X      while ((*dd != '\0') && (*ss != *dd))
X	dd ++;
X
X      if (*ss == *dd) {
X	*ss = '\0';
X	ss ++;
X	if (*ss == '\0')	/* Case where delim is last char */
X	  nn++;
X	break;
X      }
X    }
X  }
X  /*
X   * Last substring delimited by '\0'
X   */
X  if (!pastArgn && ((arg = va_arg (pvar, char **)) != (char **) 0))
X    *arg = ss;
X  pastArgn = arg == (char **)0;
X
X  /*
X   * Put NULL in remaining arg positions.
X   */
X  if (!pastArgn)
X    while ((arg = va_arg (pvar, char **)) != (char **) 0)
X      *arg = (char *) 0;
X
X  va_end (pvar);
X  
X  return (nn);
X}
X
Xchar *
Xsetenv (env, val, replace)
X     char *env, *val;
X     int replace;
X{
X  char *oldValue, *pp, *getenv();
X
X  oldValue = getenv (env);
X  
X  pp = (char *) malloc (strlen (env) + strlen (val) + 2);
X  if (pp == (char *) NULL) {
X    (void) fprintf (stderr, "Out of memory.\n");
X    exit (1);
X  }
X  (void) sprintf (pp, "%s=%s", env, val);
X  if (putenv (pp) != 0) {
X    (void) fprintf (stderr, "Out of memory.\n");
X    exit (1);
X  }
X
X  return (oldValue);
X}
SHAR_EOF
$TOUCH -am 0502134492 misc/unilogin.c &&
chmod 0644 misc/unilogin.c ||
echo "restore of misc/unilogin.c failed"
set `wc -c misc/unilogin.c`;Wc_c=$1
if test "$Wc_c" != "4988"; then
	echo original size 4988, current size $Wc_c
fi
exit 0
