rsalz@bbn.com (Rich Salz) (02/17/88)
Submitted-by: jim nelson <ecsgate!ecsvax!nelson> Posting-number: Volume 13, Issue 43 Archive-name: autoadd Autoadd reads lines from an input file, creates required lines in /etc/passwd, calls mkdir(1) to create required directories, creates .profile files, etc. It's designed for educational environments. # To unbundle, sh this file echo MANIFEST 1>&2 sed -e 's/^X//' >MANIFEST <<'End' XMANIFEST XREADME Xautoadd.8 XMakefile Xautoadd.h Xexample Xausr Xkusr Xalready.c Xecpw.c Xexists.c Xinitfiles.c Xkindex.c Xmain.c Xparse.c Xquit.c Xtryagain.c End echo README 1>&2 sed -e 's/^X//' >README <<'End' XAutoadd is yours for the taking. If you like it, use it. XIf not, trash it. I wrote it just for fun, and because I Xneeded it. It's hereby put in the public domain; no Xcopyright, no send-me-money, no nothing. X XAutoadd is a batch adduser program. It's in C, with one Xcall to the "system()" (to mkdir) (why reinvent TWO wheels?) X(Oh yeah, I think I also sytem("cp ....") just from sheer Xlaziness). X XI'd have to admit to a little hubris, though, in titling the Xman page with a ".8" suffix instead of ".1". Feel free to Xmove it to ".1" if you see fit. X XI have included my own /etc/ausr and /etc/kusr (Bourne) shell Xscripts just for comparison with the autoadd.c program. Throw Xthem away quickly if you have your own favorite (which most Xeverybody should, I guess.). X XNB: this is one of those "Oh, he wants me to run this as root?" Xprograms. Well, the source is not very long; and it's intended Xto be totally readable to the most casual of observers, so Xuse if you like, but X X#include <standard.disclaimer> X XSee mostly the autoadd.h comments and #defines, but also take Xa look at initfiles.c . X--- jhn X XOh yeah, all these sources should be looked at with tab stops Xset at four. They were created using vi with autoindent and Xtabstops at four. Stops of eight will make some of the lines run Xoff the screen. Alternatively, run them thru sed and change Xall \t to four blanks (which I did not do, in the interest of Xkeeping the byte count down). X--- jhn End echo autoadd.8 1>&2 sed -e 's/^X//' >autoadd.8 <<'End' X.ig X @(#)autoadd.8 X.. X.TH AUTOADD 8 X.UC 4 X.SH NAME Xautoadd \- add class rosters to system X.SH SYNOPSIS X.B autoadd X[ Xfilename X] X.SH DESCRIPTION X.I Autoadd Xreads lines from an input file, creates required lines in X/etc/passwd, calls mkdir(1) to create required directories, Xcreates .profile files, etc., Xto add a batch of users to the system. Optionally, it will Xappend to the /etc/accesstab file for use with "access". XSupplied in source form. See comments and tunable parameters Xin autoadd.h for more info. X.PP XNo command line parameters are provided; this program will Xbe used rarely (twice or thrice per semester, typically) and Xcan be configured by #defines in the source. X.PP XKeywords are: X.TP X.B prof: professor X.TP X.B group: group X.TP X.B alias: for a mailrc X.TP X.B disk: partition X.TP X.B passwd: password X.TP X.B firstprog: last line of profile X.PP XOther input lines are of the form: X.TP X.B lastname i i X.PP XThe /etc/passwd file is read to determine the largest user number Xthere, and the new people are assigned user numbers from there up. X.SH FILES X.ta 2i X/etc/passwd password file X.br X/etc/accesstab (optional) for professor:student lines X.br X./mailrc alias list for sending to professor X.SH AUTHOR XJim Nelson, UNC-Wilmington (nelson@ecsvax.uucp) 919-395-3300 X.SH BUGS X Must be run as root. End echo Makefile 1>&2 sed -e 's/^X//' >Makefile <<'End' XCFLAGS= XLDFLAGS=-s XLINTFLAGS=-hbx X XSOURCES= main.c parse.c kindex.c exists.c \ X ecpw.c quit.c initfiles.c already.c tryagain.c X XOBJS= main.o parse.o kindex.o exists.o \ X ecpw.o quit.o initfiles.o already.o tryagain.o X Xautoadd: $(OBJS) autoadd.h X cc $(LDFLAGS) -o autoadd $(OBJS) X Xmain.o initfiles.o tryagain.o parse.o: autoadd.h X Xautoadd.shar: MANIFEST README autoadd.8 Makefile autoadd.h example \ X ausr kusr $(SOURCES) X shar MANIFEST README autoadd.8 Makefile autoadd.h example \ X ausr kusr $(SOURCES) >autoadd.shar X Xlint: $(SOURCES) autoadd.h X lint $(LINTFLAGS) autoadd.h $(SOURCES) End echo autoadd.h 1>&2 sed -e 's/^X//' >autoadd.h <<'End' X/* X"autoadd" -- a batch account-setter-upper. for adding whole class Xrosters to unix machines. Xby: j. nelson, univ. nc-wilmington, dept. math. sciences, Xwilmington nc 28403, 919-395-3300. X XThe idea here is to allow a student assistant or other partially Xtrusted assistant to enter the class roster, and then in one Xswell-foop, add all those folks to the system. This can be either Xpermitted to the assistant or reserved to the sysop, but requires Xthat the program be run as root (at least it does on my machines). X XAn input file consists of a few "keyword" lines, followed by the Xclass roster in "lastname fi mi" form. X XKeywords : X"prof:ssss" professor for "accesstab" file X this is for that neat program that came down the X wire a while back that allows someone to access X another directory by effectively "becoming" them. X If not using, comment out the following line: */ X#define ACCESS X/* X"disk:/sssss" parent directory, e.g. /usr3, /stoonts, etc. X"firstprog:ssss" this will be the last line of .profile X"shell:xxxxx" shell; 0 means no entry */ X#define PROFILE "/.profile" /*will have parentdir prepended*/ X#define LOGIN "/.login" X#define STDPROFILE "/etc/stdprofile" X/* X"alias:sssss" for manually moving into the prof's .mailrc file X"group:nnn" group X"passwd:xxxxxx" password (will be same for all these users, but salt X is randomly selected) X"password:xxxx" (same as passwd) X special case: 1 means use username as password. X XAny line containing one of the keywords is processed for the keyword Xvalue. Null lines, blank lines, and lines beginning with # are ignored. XOther lines are presumed to be name-lines of the form Xlastname f m Xthat is, lastname firstinitial middleinitial Xseparated by blanks. XThe lastname may be of any length, but will be truncated to ML (default Xis 7) chars before applying any of the algorithms. fi and mi should Xbe only single characters, but the parser will accept any number, Xand will truncate them to single chars. XAlso accepts usernames of the form abc, where abc is the person's Xfi mi li, as some system admins like to use, e.g. I would be X"jhn" (James H Nelson), and "Joe Bob College" would be "jbc". XThe program assumes that "jhn" is the lastname, and forces fi Xand mi to be '1' for purposes of the algorithm. XThe algorithm first tries lastname, then filastname, then Xlastnamefi, then filastnamemi, etc., etc., finally resorting to Xprepending digits to usernames if all else fails (this is guaranteed Xto work unless you have a huge number of users (!)). The exact Xalgorithm is clear from reading the code in tryagain(). XSee alse the example file. X*/ X X#include <stdio.h> X X X/* these next includes probably will not work everywhere */ X/* they DO work on SysVr2 (3b2/300) and a BSD4.1-derived Xknockoff (lmc -- GENIX on a nsc16032) */ X#include <string.h> /*maybe strings.h ???*/ X#include <sys/types.h> /*maybe don't need sys ??? */ X#include <sys/stat.h> /* ditto */ X#include <errno.h> /*only for ENOENT*/ /*if fails, forget it! */ X X/* next three are individually tunable parameters */ X#define MAXNU 1300 /*max number of entries in /etc/passwd */ X#define ROOT 0 /* just in case your root is not uid==0 (?weird?) */ X#define ML 7 /*maximum length of a login-name.*/ X/* 7 is a nice length, 'cause tabs work better, but this can be X anything within reason */ X X#define null '\0' /*just for ease of typing*/ /* not same as NULL */ X Xextern void exit(); /* for lint */ X X#ifdef MAIN /*so only see once; main.c will define MAIN, Xbut nobody else will*/ X X/* some of the following might need to be lengthened if sysop Xallows ridiculously long login names */ X Xint euid; X/* euid = geteuid(); */ /*to see if we're dangerous */ X/*this will be done very early in main() */ X/* Autoadd does slightly different things depending on whether X user is root or not, e.g. /etc/passwd vs. ./passwd , etc. X Examine the code carefully before running at all, and then re- X examine it before running as root. This is not a disk-polisher or X one of those other nasties, (DO NOT take my word for it, look at X the code!) but it does have to run as root to be X effective (not necessarily setuid root, just "effective uid" X of root), 'cause it must append to /etc/passwd and create X directories in /"disk". (unless you let just anybody do those X things!) X*/ X/* some defaults:*/ X#define GROUP "100" /*why not?*/ X#define DISK "/usr4" /*our current place to stash stoonts*/ X#define SHELL "0" /* 0 means Bourne shell */ X#define ALIAS "csc101" /*we don't have a csc101, so why not?*/ X#define FIRSTPROG "0" /* default no startup program */ X#define PROFESSOR "nelson" /* make "0" (with quotes) for none*/ X#define PASSWD "0" /*no default password*/ X#define DISLIST "./mailrc" /*filename of where to put alias list*/ X/*notice that several of the variables default if the first X(i.e. zeroth) character of a string is the character '0' , but the Xabove defines must be in double-qoutes, not single-quotes, becuz Xthey're used in strcpy() statements. XA couple of other things: GROUP must be a string, not an integer; Xthe leading / is optional on DISK (it'll be forced if omitted); XI don't have ksh, so the only way to make it the default is to Xhack on the source; be sure the look at ecpw.c closely if worried Xabout passwords. X*/ X X/* Global variables: */ Xchar *user[MAXNU],*malloc(); /* we have only about 120, but ...*/ Xchar ecptex[20]; /* large enuff to hold an encrypted password*/ Xchar infile[100]; /*the input filename ... 30 should be plenty*/ Xchar line[142],lastname[50],fi[2],mi[2]; Xchar profname[30],diskname[20],groupname[20],passwordname[20], X username[40],aliasname[40],firstprog[40],parentdir[40]; Xchar dislist[60],passwd[60],proffile[60] ; X#endif /*MAIN*/ End echo example 1>&2 sed -e 's/^X//' >example <<'End' X# fortran77 Xgroup:195 Xalias:csc111 Xprof:herbst Xdisk:usr Xpassword:beginner X# force them into the menu-shell as the last line X# of their .profile Xfirstprog:/usr/uncw/msh X Xnelson brain dead Xmr Xmmr Xal-anon muhammad mustafa Xshell:/bin/csh Xpodgornowitz a a Xpodgornowitz a b X#next person should be only one who has password same as login Xpasswd:1 Xpodgornowitz b a Xpasswd:0 X X# intro comp sci II section 1 Xprof:knuth Xdisk:/usr1 X#i think this is the unit of albanian currency ? Xpasswd:zlotny Xgroup:177 Xfirstprog:0 Xalias:csc12201 Xshell:0 Xcampus big man on Xcretin a a Xcretin a b X# just to see if this works Xshell:/bin/ksh Xcretin b a Xshell:/bin/csh Xcretin b b X# go back to Bourne shell Xshell:0 Xcretin b b Xjhn Xcollege suzy coed Xbch X# X# operating systems Xprof:ast Xalias:csc342 Xpasswd:Wachtwoord Xgroup:178 Xdisk:usr3 Xfirstprog:0 X Xcretin a a Xcretin a b Xcretin b a Xcollege jim bob Xcretin b b Xbch X X# programming languages Xprof:dmr Xpasswd:0 Xalias:csc334 Xdisk:/usr2 Xgroup:179 Xfirstprog:0 X Xcretin a a Xfrn Xcretin a b Xcollege joe bob Xcretina b a Xcretinal b a Xcretinally terminal hazeltine Xcretin b b End echo ausr 1>&2 sed -e 's/^X//' >ausr <<'End' XP#I'm not sure how to shar shell scripts, so I just arbitrarily XP#put a capital letter in column 1. sed should snarf it fine. XP#!/bin/sh XP#adduser shell script ... bypasses most of the XP# agony the sysadm (SysVr2) route makes you go through XP#jhn 06jan87 XPcase `uname` in XP 3b2b) XP echo "puttem where? 2,3,or 4 [default is /usr] \c" XP read blonk XP case $blonk in XP 2) scrod=2;; XP 3) scrod=3;; XP 4) scrod=4;; XP "") scrod="";; XP *) echo "valid responses are <cr>, 2, 3, or 4. Bye..."; XP exit;; XP esac ;; XP 3b2a) scrod="";; XPesac #end case uname XPscrod=usr${scrod} XPecho "putting them in /$scrod XP please wait ... looking for next avail userno" XP XPgroup=100 XPnextuser=`/usr/bin/awk -F: '$3+0>num+0 {num=$3+0} XPEND {print 1+num}' /etc/passwd ` XP#nextuser=`expr $nextuser + 1` XPecho next available userno is $nextuser XP XPwhile : ; do XPecho "enter fullname \c" XPread fullname XPcase $fullname in XP "") echo "null user fullname not allowed"; exit 1;; XPesac XP XPecho "enter loginname \c" XPread login XPcase $login in XP "") echo "null user name not allowed"; exit 1;; XPesac XPecho "enter usernumber [$nextuser] \c" XPread user XPcase $user in XP "") user=$nextuser;echo "using $user";; XPesac XPnextuser=`expr $user + 1` XPloop=true XPwhile : XPdo XP echo "enter group (? for cat /etc/group) [$group] \c" XP read xroup XP case $xroup in XP \?) cat /etc/group;; XP "") break;; XP *) group=$xroup;break;; XP esac XPdone XPcase $group in XP "") echo null group not allowed ... bye; exit 1;; XPesac XP XP/usr/bin/awk -F: '$1=='\"$login\"' || $3=='\"$user\"' {print}' /etc/passwd\ XP >/tmp/au$$ XPalready="" XPif test -s /tmp/au$$ XPthen XP /bin/cat /tmp/au$$ XP echo "login=$login or user=$user in use ..." XP rm -f /tmp/au$$ XP already=1 XPfi XPif test -d /${scrod}/$login XPthen XP echo "/${scrod}/$login already exists ... !" XP rm -f /tmp/au$$ XP already=1 XPfi XP XP XPcase $already in XP "") XP /bin/mkdir /${scrod}/$login XP echo "$login::$user:$group:$fullname:/${scrod}/$login:" XP echo "ok? [y] \c" XP read doit XP case $doit in XP n) /bin/rmdir /${scrod}/$login; exit 1;; XP esac XP /bin/chmod u+w /etc/passwd XP echo "$login::$user:$group:$fullname:/${scrod}/$login:">>/etc/passwd XP sync XP /bin/chmod u+w /etc/passwd XP tail -2 /etc/passwd XP /bin/chown $user /${scrod}/$login XP /bin/chgrp $group /${scrod}/$login XP /bin/chmod 755 /${scrod}/$login XP /bin/cp /etc/stdprofile /${scrod}/$login/.profile XP /bin/chown $user /${scrod}/$login/.profile XP /bin/chgrp sys /${scrod}/$login/.profile XP /bin/chmod gu+w /${scrod}/$login/.profile XP case $umsk in XP "") echo "enter umask [22]: \c" XP read umsk XP case $umsk in XP "") umsk=22;; XP esac XP ;; XP esac XP echo "umask $umsk">>/${scrod}/$login/.profile XP echo "menu-shell initially? [n]: \c" XP read yesno XP case $yesno in XP y) echo "/usr/uncw/msh" >> /${scrod}/$login/.profile;; XP *) echo "menu-shell not selected";; XP esac XP echo "give him a password? [y]: \c" XP read yesno XP case $yesno in XP y|"") /bin/passwd $login;; XP *) echo "no password set for $login";; XP esac XP rm -f /tmp/au$$ XP echo "put password aging in effect? [y]: \c" XP read yesno XP case $yesno in XP y|"") /etc/agepw $login;; XP n) echo password aging not set for $login;; XP esac XP;; XPesac #end of case $already=="" XPcase $god in XP "") echo "enter godname []: \c" XP read god;; XP *) ;; XPesac XPcase $god in XP "") ;; XP *) echo "$god:$login">>/etc/accesstab XP ;; XPesac XPecho '***** done ***** XP XP want to add another user? [y] \c' XPread domore XPcase $domore in XP n) exit;; XPesac XPdone XP End echo kusr 1>&2 sed -e 's/^X//' >kusr <<'End' XPcase $1 in XP "") echo "usage: /etc/kusr username"; exit 1;; XPesac XPx=`/usr/bin/awk -F: '$1=='\"$1\"' {print $6}' /etc/passwd ` XPcase $x in XP/|/etc|/bin|/usr/bin|/usr/uncw|/lib|/usr/lib|/usr/spool ) \ XP echo "rm -r $x would be considered antisocial behavior";exit 1;; XP "") echo no such user...bye; exit 1;; XP /usr* ) ;; XP *) echo "wtf?? x=$x"; exit 1;; XPesac XP XP#echo "about to rm -r $x ok [y] \c" XP#read ans XPans=y XPcase $ans in XP "") rm -r $x;; XP n) exit;; XP y) rm -r $x;; XP *) echo "invalid response ... $x not removed";exit;; XPesac XP#grep -v $1 /etc/passwd > /tmp/kusr$$ XP/usr/bin/awk -F: '$1!='\"$1\"' {print }' /etc/passwd >/tmp/kusr$$ XP#diff /etc/passwd /tmp/kusr$$ XP#echo "ok? [y] \c" XP#read ans XPans=y XPcase $ans in XP n) exit;; XP ""|y) XP /bin/rm -f /usr/mail/$1; XP cp /tmp/kusr$$ /etc/passwd ; XP /bin/rm /tmp/kusr$$;; XP *) echo "invalid response interpreted as \"no\" ";exit;; XPesac End echo already.c 1>&2 sed -e 's/^X//' >already.c <<'End' X X#ifndef NULL X#include <stdio.h> X#endif Xalready(p) Xchar *p; X{ X int i; X extern char *user[]; X i=0; X /*printf("in already, looking for ...%s...",p);*/ X while(user[i]!=NULL){ X if(strcmp(p,user[i])==0){/*printf("found at %d...",i);*/ X return 1;} X i++; X } X /*printf("not found, i=%d...",i);*/ X return 0; X} End echo ecpw.c 1>&2 sed -e 's/^X//' >ecpw.c <<'End' X Xchar salts[63]= /*must be 63 to leave room for the null*/ X"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; X/*1234567890123456789012345678901234567890123456789012345678901*/ X/*0000000001111111111222222222233333333334444444444555555555566*/ X/* don't use / or . because one manual says one thing, and the other X manual says another thing. stick with letters and digits for salt. X*/ X Xecpw(pwd) Xchar *pwd; X{ X /*side effect: modifies ecptex*/ X extern char ecptex[]; X void extern exit(); X char *result,*crypt(); X char salt[3]; X salt[0]=salts[rand()%62]; X salt[1]=salts[rand()%62]; X salt[2]='\0'; X X result=crypt(pwd,salt); X (void) strcpy(ecptex,result); X} End echo exists.c 1>&2 sed -e 's/^X//' >exists.c <<'End' X X#ifndef ENOENT X#include <sys/types.h> X#include <sys/stat.h> X#include <errno.h> X#endif Xexists(filename) Xchar *filename; X{ X extern int errno; X struct stat buf; X if(stat(filename,&buf)== -1 && errno==ENOENT)return 0; X return 1; X} End echo initfiles.c 1>&2 sed -e 's/^X//' >initfiles.c <<'End' X#include "autoadd.h" Xinitfiles() X{ X extern int euid; X extern char passwd[], proffile[]; X if(euid==ROOT){ X strcpy(passwd,"/etc/passwd"); X strcpy(proffile,"/etc/accesstab");} X else{ X strcpy(passwd,"passwd"); X strcpy(proffile,"accesstab");} X} End echo kindex.c 1>&2 sed -e 's/^X//' >kindex.c <<'End' Xkindex(s,t) Xchar s[],t[]; X{ X extern void exit(); X/* slightly beefed up version of "index" from the middle Xof p. 67 K&R */ X int c,i,j,k; X c=s[0]; X if(c==0){i=puts("in kindex ... dummy, s[0] is zero");j=i; X puts(t); X if(i==j)exit(1);} X c=t[0]; X if(c==0){i=puts("in kindex ... dummy, t[0] is zero");j=i; X puts(s); X if(j==i)exit(1);} X for(i=0;s[i] !='\0'; i++){ X for(j=i,k=0;t[k] !='\0' && s[j]==t[k];j++,k++) X ; X if(t[k]=='\0')return (i); X } X return(-1); X} X End echo main.c 1>&2 sed -e 's/^X//' >main.c <<'End' X#define MAIN X#include "autoadd.h" X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X char systemline[100],profilename[100],directory[100],shellname[100]; X char answer[9]; X int i,j,k,how,nextu,unum,maxunum,groupnumber,firstalias,cshell; X extern int geteuid(); X FILE *fp1,*fp2,*fp3,*fp4,*fopen(); X long time(); X void srand(); /*to make lint shut up*/ X X/*some executable initializations:*/ X euid=geteuid(); /*should be first executable stmt*/ X initfiles(); /*executably set sensitive filenames*/ X strcpy(groupname,GROUP); /*100 our default group*/ X strcpy(diskname,DISK); /* /usr our default disk*/ X strcpy(shellname,SHELL); X strcpy(aliasname,ALIAS); X strcpy(firstprog,FIRSTPROG); X strcpy(profname,PROFESSOR); X strcpy(passwordname,PASSWD); X strcpy(dislist,DISLIST); X firstalias=cshell=0; X for(i=0;i<MAXNU;++i)user[i]=NULL; X srand((unsigned int)time(0L)); X X/*open the password file in read mode to see who's already there */ X fp1=fopen("/etc/passwd","r"); X if(fp1==NULL)quit("/etc/passwd"); X j=0; X maxunum= -1; X while(fgets(line,120,fp1)==line){ X i=kindex(line,":"); X line[i]='\0'; X k=i+1; X while(line[k]!=':')k++; X sscanf(&line[k+1],"%d",&unum); X if(unum>maxunum)maxunum=unum; X user[j]=malloc((unsigned)i+1); X strcpy(user[j],line); X j++; X } X nextu=j; X if(fclose(fp1)<0)quit("/etc/passwd"); X/* thru reading /etc/passwd */ X if(argc>=2) X strcpy(infile,argv[1]); X else{ X printf("input filename:"); X scanf("%s",infile); X } X/* open the input file in read mode */ X fp1=fopen(infile,"r"); X if(fp1==NULL)quit(infile); X/* open /etc/passwd in append mode */ X fp2=fopen(passwd,"a"); X if(fp2==NULL)quit(passwd); X#ifdef ACCESS X/* open /etc/accesstab in append mode */ X fp3=fopen(proffile,"a"); X if(fp3==NULL)quit(proffile); X#endif X profname[0]=null; X/* open mailrc in append mode */ X fp4=fopen(dislist,"a"); X if(fp4==NULL)quit(dislist); X/* process input file */ X while(fgets(line,120,fp1)==line){ X if(*line==' ' || *line=='#' || *line=='\n' || *line==null) X continue; X for(i=0;line[i];i++)if(line[i]<' '){ X line[i]='\0'; X break; X } X#ifdef ACCESS X if((i=kindex(line,"prof:"))>=0){ X strcpy(profname,&line[i+strlen("prof:")]); X } X else X#endif X X if((i=kindex(line,"disk:"))>=0){ X strcpy(diskname,&line[i+strlen("disk:")]); X if(diskname[0]!='/'){ X strcpy(diskname,"/"); X strcat(diskname,&line[i+strlen("disk:")]);} X if(euid!=ROOT){ X strcpy(parentdir,"."); X strcat(parentdir,diskname);} X else X strcpy(parentdir,diskname); X if(!exists(parentdir)){ X /*if not root, don't bother asking, just do it */ X if(euid==ROOT){ X printf( X "%s doesn't seem to exist, shall I mkdir it?(y/n): " X ,parentdir); X scanf("%s",answer); X if(kindex(answer,"y")!=0)quit(parentdir); X } X /*else{*/ X strcpy(systemline,"mkdir "); X strcat(systemline,parentdir); X system(systemline); X if(!exists(parentdir))quit(parentdir); X /*}*/ X } X } X X else if((i=kindex(line,"firstprog:"))>=0){ X strcpy(firstprog,&line[i+strlen("firstprog:")]); X } X else if((i=kindex(line,"alias:"))>=0){ X strcpy(aliasname,&line[i+strlen("alias:")]); X if(aliasname[0]!='0'){ X fprintf(fp4, X firstalias?"\nalias %s ":"alias %s ",aliasname); X firstalias=1; X } X } X X X else if((i=kindex(line,"group:"))>=0){ X strcpy(groupname,&line[i+strlen("group:")]); X sscanf(groupname,"%d",&groupnumber); X } X X else if((i=kindex(line,"shell:"))>=0){ X strcpy(shellname,&line[i+strlen("shell:")]); X if(kindex(shellname,"csh")>0)cshell=1;else cshell=0; X } X X else if((i=kindex(line,"passwd:"))>=0){ X strcpy(passwordname,&line[i+strlen("passwd:")]); X } X X else if((i=kindex(line,"password:"))>=0){ X strcpy(passwordname,&line[i+strlen("password:")]); X } X else{ X if(kindex(line,":")>=0){ X printf("IGNORED:%s\n",line);continue;} X parse(); X strcpy(username,lastname); X how=0; Xfor(;;){ X strcpy(directory,parentdir); X strcat(directory,"/"); X strcat(directory,username); X if(exists(directory) || already(username)) X { X tryagain(how); X username[ML]=null; X how++; X } X else X break; X} X strcpy(systemline,"mkdir "); X strcat(systemline,directory); X system(systemline); X if(!exists(directory))quit(directory);/*failed*/ X X X user[nextu]=malloc((unsigned)strlen(username)+1); X strcpy(user[nextu],username); X nextu++; X X if(passwordname[0]=='0' || passwordname[0]==null) X ecptex[0]=null; X else if (passwordname[0] == '1') X ecpw(username); X else X ecpw(passwordname); X X fprintf(fp2,"%s:%s:%d:%s:%s:%s/%s:%s\n" X ,username,ecptex,++maxunum,groupname,line, X diskname,username,shellname[0]!='0'?shellname:""); X if(aliasname[0]!='0') X fprintf(fp4,"\\\n%s ",username);/*for dislist*/ X X unum=maxunum; X#ifdef ACCESS X if(*profname&&*profname!='0') X fprintf(fp3,"%s:%s\n",profname,username); X#endif X X strcpy(profilename,directory); X strcat(profilename,cshell?LOGIN:PROFILE); X if(!exists(profilename)){ X strcpy(systemline,"cp "); X strcat(systemline,STDPROFILE /*"/etc/stdprofile "*/); X strcat(systemline," "); /*just in case*/ X strcat(systemline,profilename); X system(systemline); X if(firstprog[0]!='0'){ X strcpy(systemline,"echo "); X strcat(systemline,firstprog); X strcat(systemline," >> "); X strcat(systemline,profilename); X system(systemline); X } X } X if(euid==ROOT){ X /*do the chowns only if running as root (effective uid)*/ X if(chown(directory,unum,groupnumber)<0)quit(directory); X if(chown(profilename,unum,3 /*3=="sys"*/)<0) X quit(profilename); X } X X X } X } /*end of file on input file */ X if(firstalias) X fprintf(fp4,"\n");/*close out the last line of dislist*/ X return 0; /* lint */ X} End echo parse.c 1>&2 sed -e 's/^X//' >parse.c <<'End' X X X X#include "autoadd.h" Xparse() X{ X int i=0; X int j; X extern char lastname[],fi[],mi[],line[]; X lastname[0]=mi[0]=fi[0]='1'; X lastname[ML]=fi[1]=mi[1]=null; X j=strlen(line); X while(line[i]==' ' && i<j)i++; X while(line[i] && line[i]!=' ' && i<ML && i<j) X {lastname[i]=line[i];i++;} X lastname[i]=lastname[ML]='\0'; X if(i>=j)return; X while(line[i]!=' ' && i<j)i++; X while(line[i]==' ' && i<j)i++; X if(i>=j)return; X fi[0]=line[i++]; X fi[1]='\0'; X if(i>=j)return; X while(line[i]!=' ' && i<j)i++; X while(line[i]==' ' && i<j)i++; X if(line[i])mi[0]=line[i]; X mi[1]='\0'; X} X End echo quit.c 1>&2 sed -e 's/^X//' >quit.c <<'End' Xquit(p) Xchar *p; X{ X extern void exit(); X puts( X"******* something went wrong here that I can't figure out********" X ); X puts(p); X puts("I'm outta here..."); X exit(1); X} End echo tryagain.c 1>&2 sed -e 's/^X//' >tryagain.c <<'End' X#include "autoadd.h" Xtryagain(how) X{ X extern char fi[],lastname[],mi[],username[]; X char temp[49]; Xswitch(how){ Xcase 0: X strcpy(temp,fi); X strcat(temp,lastname); X break; Xcase 1: X strncpy(temp,lastname,ML-1); X temp[ML-1]='\0'; X strcat(temp,fi); X break; Xcase 2: X strncpy(temp,lastname,ML-2); X temp[ML-2]='\0'; X strcat(temp,fi); X strcat(temp,mi); X break; Xcase 3: X strcpy(temp,fi); X strcat(temp,mi); X strcat(temp,lastname); X break; Xcase 4: X strcpy(temp,fi); X strncat(temp,lastname,ML-2); X temp[ML-1]='\0'; X strcat(temp,mi); X break; Xdefault: X sprintf(temp,"%d%s",how>4?how-4+1:how /*this 4 is dangerous*/ X ,lastname); X break; X} X/* temp[ML]='\0';*/ /* let main do it!*/ X strcpy(username,temp); X} End exit -- For comp.sources.unix stuff, mail to sources@uunet.uu.net.