home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume8 / mcp / part03 < prev    next >
Text File  |  1987-02-05  |  51KB  |  2,167 lines

  1. Subject:  v08i043:  Account creation/manipulation program, Part03/08
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Kyle Jones <xanth!kyle>
  6. Mod.sources: Volume 8, Issue 43
  7. Archive-name: mcp/Part03
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If all goes well, you will see the message "End of archive 3 (of 8)."
  13. # Contents:  man/sigs.n man/vigs.n misc/freeze misc/sorry src/Copyright
  14. #   src/Makefile src/account.c src/account.h src/add.c src/alias.c
  15. #   src/backup.c src/class.c src/class.h src/command.h src/gpa.h
  16. # Wrapped by rs@mirror on Fri Feb  6 15:55:53 1987
  17. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  18. echo shar: extracting "'man/sigs.n'" '(608 characters)'
  19. if test -f 'man/sigs.n' ; then 
  20.   echo shar: will not over-write existing file "'man/sigs.n'"
  21. else
  22. sed 's/^X//' >man/sigs.n <<'@//E*O*F man/sigs.n//'
  23. X.TH SIGS 5
  24. X.SH NAME
  25. Xsigs \- mcp Special Interest Groups
  26. X.SH SYNOPSIS
  27. XSIGFILE
  28. X.SH DESCRIPTION
  29. X.I Sigs
  30. Xcontains the names and descriptions of all the 
  31. X.I mcp(l)
  32. Xsigs.
  33. XThe format for the file is:
  34. X.sp
  35. Xname <sp> description length <sp> expiration time <nl>
  36. X.br
  37. Xdescription...
  38. X.sp
  39. XThe description length is the number of characters in the description
  40. Xwhich beigns immedaitely after the name line.
  41. XThe expiration date is given in the number of seconds since Jan. 1, 1970.
  42. XUnless this file is munged by some calamity, it need never be edited manually
  43. Xas
  44. X.I mcp
  45. Xhandles all modification of it.
  46. X.SH SEE ALSO
  47. X.I mcp(l)
  48. @//E*O*F man/sigs.n//
  49. if test 608 -ne "`wc -c <'man/sigs.n'`"; then
  50.     echo shar: error transmitting "'man/sigs.n'" '(should have been 608 characters)'
  51. fi
  52. fi # end of overwriting check
  53. echo shar: extracting "'man/vigs.n'" '(498 characters)'
  54. if test -f 'man/vigs.n' ; then 
  55.   echo shar: will not over-write existing file "'man/vigs.n'"
  56. else
  57. sed 's/^X//' >man/vigs.n <<'@//E*O*F man/vigs.n//'
  58. X.TH VIGS 5
  59. X.SH NAME
  60. Xvigs \- mcp Very Importans Groups file
  61. X.SH SYNOPSIS
  62. XVIGFILE
  63. X.SH DESCRIPTION
  64. X.I Vigs
  65. Xcontains a list of groups, one per line, that the
  66. X.I mcp(l)
  67. Xprogram is to consider important.
  68. XUsers with numerical group ID's that map to a group that is a
  69. X.I vig
  70. Xget special treatment; they are not considered
  71. X.I deadbeats
  72. Xeven when not a member of a class or sig.  When executing
  73. X.B freeze-user,
  74. Xconfirmation is requested before freezing a member of a
  75. X.I vig.
  76. X.SH SEE ALSO
  77. X.I mcp(l), group(5)
  78. @//E*O*F man/vigs.n//
  79. if test 498 -ne "`wc -c <'man/vigs.n'`"; then
  80.     echo shar: error transmitting "'man/vigs.n'" '(should have been 498 characters)'
  81. fi
  82. fi # end of overwriting check
  83. echo shar: extracting "'misc/freeze'" '(424 characters)'
  84. if test -f 'misc/freeze' ; then 
  85.   echo shar: will not over-write existing file "'misc/freeze'"
  86. else
  87. sed 's/^X//' >misc/freeze <<'@//E*O*F misc/freeze//'
  88. X#!/bin/sh
  89. X
  90. X/bin/cat << Brrrrr!
  91. X
  92. XYour account has been whisked to the mylar deep freeze. There it will
  93. Xremain for a period of one (1) year, at which point your files and other
  94. Xhallucinogens will serve as a repast for David Letterman's hounds.
  95. X
  96. XIf you are outraged by this, curse loudly... someplace else.
  97. X
  98. XBrrrrr!
  99. X
  100. X/usr/ucb/mail -s "climate" tadguy@amon-re kyle@amon-re << Hey!
  101. XGad it's cold in here.
  102. XHey!
  103. X
  104. X/usr/bin/sleep 15
  105. @//E*O*F misc/freeze//
  106. if test 424 -ne "`wc -c <'misc/freeze'`"; then
  107.     echo shar: error transmitting "'misc/freeze'" '(should have been 424 characters)'
  108. fi
  109. fi # end of overwriting check
  110. echo shar: extracting "'misc/sorry'" '(346 characters)'
  111. if test -f 'misc/sorry' ; then 
  112.   echo shar: will not over-write existing file "'misc/sorry'"
  113. else
  114. sed 's/^X//' >misc/sorry <<'@//E*O*F misc/sorry//'
  115. X#!/bin/sh
  116. X
  117. X/bin/cat << Aughghghgh!!!
  118. X
  119. XSorry, your account has been disabled.  Why?  Heh, heh you know why.
  120. XTo make arrangements for restitution to the aggrieved parties, contact
  121. Xtheir attorneys.  For now, go away.
  122. X
  123. XAughghghgh!!!
  124. X
  125. X/usr/ucb/mail -s "the rogue returneth" syskids << Yawn...
  126. XHey!!  Where'd my account go?!
  127. XYawn...
  128. X
  129. X/usr/bin/sleep 15
  130. @//E*O*F misc/sorry//
  131. if test 346 -ne "`wc -c <'misc/sorry'`"; then
  132.     echo shar: error transmitting "'misc/sorry'" '(should have been 346 characters)'
  133. fi
  134. fi # end of overwriting check
  135. echo shar: extracting "'src/Copyright'" '(385 characters)'
  136. if test -f 'src/Copyright' ; then 
  137.   echo shar: will not over-write existing file "'src/Copyright'"
  138. else
  139. sed 's/^X//' >src/Copyright <<'@//E*O*F src/Copyright//'
  140. X(c) 1986 by Kyle E. Jones
  141. X
  142. XAll sources and documentation of this mcp distribution are
  143. Xincluded in this copyright, but permission is granted to
  144. Xcopy and redistribute any part of this distribution, provided
  145. Xthat this notice is a conspicuous part of the redistribution,
  146. Xand that no part of this distribution is sold.
  147. X
  148. XThis software is distributed 'as is', without warranties of any kind.
  149. @//E*O*F src/Copyright//
  150. if test 385 -ne "`wc -c <'src/Copyright'`"; then
  151.     echo shar: error transmitting "'src/Copyright'" '(should have been 385 characters)'
  152. fi
  153. fi # end of overwriting check
  154. echo shar: extracting "'src/Makefile'" '(6105 characters)'
  155. if test -f 'src/Makefile' ; then 
  156.   echo shar: will not over-write existing file "'src/Makefile'"
  157. else
  158. sed 's/^X//' >src/Makefile <<'@//E*O*F src/Makefile//'
  159. X#
  160. X# DESTDIR should be where the executable is to be installed
  161. X#
  162. XDESTDIR = /etc
  163. X
  164. X# For Suns:
  165. X#
  166. X# If CLIENTS is defined 'make install' will use rcp and rsh to install
  167. X# mcp on the client machines.
  168. X#
  169. X# CLIENTS = io ganymede callisto amalthea europa 
  170. X
  171. X#
  172. X# Mcp when installed will only be executable by the super-user
  173. X# and members of GROUP.
  174. X#
  175. XGROUP    = account
  176. X
  177. X#
  178. X# Using -O under Sun UNIX 3.0 is not advivsed
  179. X#
  180. XCFLAGS    = -O
  181. X
  182. XSRCS =    init.c\
  183. X    account.c add.c alias.c backup.c bind.c build.c ckp.c class.c\
  184. X    complete.c date.c describe.c disable.c edit.c errmsg.c exists.c\
  185. X    exit.c exits.c freeze.c gpa.c groupmap.c job.c lastlog.c list.c\
  186. X    lists.c load.c main.c mem.c misc.c pause.c pwlock.c range.c\
  187. X    remove.c report.c save.c shell.c sig.c signals.c sort.c tty.c\
  188. X    update.c version.c yesno.c
  189. X
  190. XOBJS =    init.o\
  191. X    account.o add.o alias.o backup.o bind.o build.o ckp.o class.o\
  192. X    complete.o date.o describe.o disable.o edit.o errmsg.o exists.o\
  193. X    exit.o exits.o freeze.o gpa.o groupmap.o job.o lastlog.o list.o\
  194. X    lists.o load.o main.o mem.o misc.o pause.o pwlock.o range.o\
  195. X    remove.o report.o save.o shell.o sig.o signals.o sort.o tty.o\
  196. X    update.o version.o yesno.o
  197. X
  198. XMYH =    account.h alias.h class.h command.h gpa.h groupmap.h\
  199. X    history.h job.h lastlog.h lists.h macros.h mem.h\
  200. X    range.h sig.h sort.h sysdep.h
  201. X
  202. Xmcp:    $(OBJS) xs.o
  203. X    @echo "Loading executable ..."
  204. X    @cc $(CFLAGS) -o mcp $(OBJS) xs.o
  205. X    @size mcp
  206. X
  207. Xinstall:    mcp
  208. X    @echo Installing mcp on `hostname`...
  209. X    @install -c -s -g $(GROUP) -m 750 mcp $(DESTDIR)
  210. X    @echo 'if test -z "$(CLIENTS)" ; then'        > i_script
  211. X    @echo 'exit 0'                    >>i_script
  212. X    @echo 'fi'                    >>i_script
  213. X    @echo 'for host in $(CLIENTS)'            >>i_script
  214. X    @echo 'do'                    >>i_script
  215. X    @echo 'echo Installing mcp on $$host...'    >>i_script
  216. X    @echo 'rcp /etc/mcp $$host:$(DESTDIR)/mcp'    >>i_script
  217. X    @echo 'rsh $$host chmod 750 $(DESTDIR)/mcp'    >>i_script
  218. X    @echo 'rsh $$host chgrp $(GROUP) $(DESTDIR)/mcp'>>i_script
  219. X    @echo 'done'                    >>i_script
  220. X    @echo 'exit 0'                    >>i_script
  221. X    @sh i_script
  222. X    @rm i_script
  223. X
  224. Xxs.o:    strings
  225. X    xstr
  226. X    cc $(CFLAGS) -c -R xs.c
  227. X
  228. Xversion.o:    version.c
  229. X    cc $(CFLAGS) -c version.c
  230. X
  231. X.c.o:
  232. X    cc $(CFLAGS) -E $< | xstr -c -
  233. X    cc $(CFLAGS) -c x.c
  234. X    mv x.o $@
  235. Xlint:
  236. X    @echo "lint -a -b -h -x $$(SRCS)"
  237. X    @lint -a -b -h -x $(SRCS)
  238. X
  239. Xlintbrush:
  240. X    @PATH=.:$$PATH nitpick $(SRCS)
  241. X    @echo "All source modules successfully linted!"
  242. X
  243. Xtags:    $(SRCS) $(MYH)
  244. X    @echo Making function and typedef tags file...
  245. X    @ctags -t $(SRCS) $(MYH)
  246. X
  247. Xclean:
  248. X    @echo Removing compilation, lint, and installation flotsam...
  249. X    @rm -f $(OBJS) core i_script exdep makedep mcp mon.out gmon.out\
  250. X        strings xs.c xs.o x.c LintErrors
  251. X    
  252. Xdepend:
  253. X    @echo Making header file dependencies...
  254. X    @(grep '^#[     ]*include[     ]*"' /dev/null $(SRCS) | sed \
  255. X        -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
  256. X        -e 's/\.c/.o/' | awk \
  257. X    'BEGIN\
  258. X            { i = 0 }\
  259. X            { len2 = length($$2) + 1}\
  260. X    FILE != $$1\
  261. X            { name[i++] = $$1; FILE = $$1;\
  262. X              line[FILE] = sprintf("\\\n\t%s", $$2);\
  263. X              currlen = len2 + 8; H = $$2}\
  264. X    FILE == $$1 && currlen + len2 > 75 && H != $$2\
  265. X            { line[FILE] = sprintf("%s\\\n\t%s",line[FILE], $$2);\
  266. X              currlen = len2 + 8; H = $$2}\
  267. X    FILE == $$1 && H != $$2\
  268. X            { line[FILE] = sprintf("%s %s", line[FILE], $$2);\
  269. X              currlen += len2; }\
  270. X    END\
  271. X            { for (j = 0; j < i; j++)\
  272. X                printf("%s%s\n", name[j], line[name[j]]); }\
  273. X            ' >> makedep)
  274. X    @echo '/^# DO NOT DELETE THIS LINE/+5,$$d' >exdep
  275. X    @echo '$$r makedep' >>exdep
  276. X    @echo 'w' >>exdep
  277. X    @cp Makefile Makefile.b
  278. X    @ex - Makefile < exdep
  279. X    @rm exdep makedep
  280. X
  281. X# DO NOT DELETE THIS LINE -- if you do, you'll be sorrrrrrry!!!
  282. X
  283. X# LINES BEYOND THIS POINT ARE USED BY 'make depend' .
  284. X# IF YOU PUT STUFF HERE, IT WILL GO AWAY.
  285. X
  286. Xinit.o:\
  287. X    sysdep.h macros.h mem.h sort.h lists.h save.h sig.h class.h\
  288. X    account.h command.h groupmap.h range.h alias.h
  289. Xaccount.o:\
  290. X    sysdep.h macros.h mem.h sort.h lists.h account.h
  291. Xadd.o:\
  292. X    sysdep.h macros.h mem.h gpa.h lists.h account.h alias.h class.h\
  293. X    groupmap.h job.h range.h sig.h sort.h save.h
  294. Xalias.o:\
  295. X    sysdep.h mem.h macros.h lists.h alias.h sort.h
  296. Xbackup.o:\
  297. X    sysdep.h mem.h save.h
  298. Xbind.o:\
  299. X    sysdep.h macros.h mem.h gpa.h lists.h account.h alias.h class.h\
  300. X    groupmap.h sig.h sort.h save.h
  301. Xbuild.o:\
  302. X    sysdep.h macros.h mem.h lists.h alias.h account.h groupmap.h\
  303. X    sort.h save.h
  304. Xckp.o:\
  305. X    sysdep.h macros.h mem.h lists.h alias.h account.h class.h sig.h\
  306. X    range.h groupmap.h save.h
  307. Xclass.o:\
  308. X    sysdep.h mem.h lists.h class.h
  309. Xcomplete.o:\
  310. X    sysdep.h macros.h mem.h history.h lists.h
  311. Xdate.o:\
  312. X    macros.h mem.h
  313. Xdescribe.o:\
  314. X    sysdep.h macros.h mem.h lists.h job.h account.h alias.h class.h\
  315. X    groupmap.h range.h sig.h save.h sort.h
  316. Xdisable.o:\
  317. X    sysdep.h mem.h lists.h account.h save.h
  318. Xedit.o:\
  319. X    sysdep.h macros.h mem.h
  320. Xerrmsg.o:\
  321. X    mem.h
  322. Xexists.o:\
  323. X    sysdep.h mem.h lists.h sort.h account.h groupmap.h class.h sig.h
  324. Xexit.o:\
  325. X    mem.h lists.h
  326. Xexits.o:\
  327. X    sysdep.h mem.h
  328. Xfreeze.o:\
  329. X    sysdep.h macros.h mem.h lists.h account.h groupmap.h save.h sort.h
  330. Xgpa.o:\
  331. X    sysdep.h mem.h gpa.h
  332. Xgroupmap.o:\
  333. X    sysdep.h macros.h mem.h lists.h groupmap.h
  334. Xjob.o:\
  335. X    sysdep.h mem.h lists.h job.h
  336. Xlastlog.o:\
  337. X    sysdep.h mem.h save.h
  338. Xlist.o:\
  339. X    sysdep.h macros.h mem.h lists.h account.h alias.h groupmap.h job.h
  340. Xlists.o:\
  341. X    sysdep.h macros.h mem.h gpa.h lists.h sort.h
  342. Xload.o:\
  343. X    sysdep.h macros.h mem.h gpa.h lists.h account.h groupmap.h save.h\
  344. X    sort.h
  345. Xmain.o:\
  346. X    sysdep.h macros.h mem.h command.h
  347. Xmem.o:\
  348. X    mem.h
  349. Xmisc.o:\
  350. X    sysdep.h macros.h mem.h lists.h range.h sort.h
  351. Xpwlock.o:\
  352. X    sysdep.h
  353. Xrange.o:\
  354. X    sysdep.h mem.h lists.h range.h
  355. Xremove.o:\
  356. X    sysdep.h macros.h mem.h lists.h gpa.h sort.h account.h alias.h\
  357. X    groupmap.h class.h job.h range.h sig.h save.h
  358. Xreport.o:\
  359. X    sysdep.h macros.h mem.h lists.h account.h alias.h class.h\
  360. X    groupmap.h range.h sig.h sort.h
  361. Xsave.o:\
  362. X    sysdep.h macros.h mem.h lists.h account.h alias.h class.h sig.h\
  363. X    range.h groupmap.h save.h
  364. Xshell.o:\
  365. X    sysdep.h macros.h mem.h
  366. Xsig.o:\
  367. X    sysdep.h mem.h lists.h sig.h
  368. Xsignals.o:\
  369. X    sysdep.h macros.h
  370. Xsort.o:\
  371. X    sysdep.h mem.h lists.h account.h alias.h class.h command.h sig.h\
  372. X    range.h groupmap.h
  373. Xupdate.o:\
  374. X    sysdep.h macros.h mem.h gpa.h lists.h account.h alias.h class.h\
  375. X    groupmap.h job.h range.h sig.h sort.h save.h
  376. Xyesno.o:\
  377. X    sysdep.h mem.h lists.h gpa.h
  378. @//E*O*F src/Makefile//
  379. if test 6105 -ne "`wc -c <'src/Makefile'`"; then
  380.     echo shar: error transmitting "'src/Makefile'" '(should have been 6105 characters)'
  381. fi
  382. fi # end of overwriting check
  383. echo shar: extracting "'src/account.c'" '(3317 characters)'
  384. if test -f 'src/account.c' ; then 
  385.   echo shar: will not over-write existing file "'src/account.c'"
  386. else
  387. sed 's/^X//' >src/account.c <<'@//E*O*F src/account.c//'
  388. X#include <stdio.h>
  389. X#include <sys/types.h>
  390. X#include <lastlog.h>
  391. X#include "sysdep.h"
  392. X#include "macros.h"
  393. X#include "mem.h"
  394. X#include "sort.h"
  395. X#include "lists.h"
  396. X#include "account.h"
  397. X
  398. Xextern    struct list AccountList;
  399. X
  400. Xstatic FILE *acf = NULL;
  401. Xstatic addr_t line[LONG_BUF];
  402. Xstatic struct account acct;
  403. X
  404. Xsetacent()
  405. X
  406. X{
  407. X    if ( !acf ) {
  408. X        acf = fopen (ACFILE, "r" );
  409. X        if (!acf) {
  410. X            perr(ACFILE);
  411. X            goodbye(1);
  412. X        }
  413. X    }
  414. X    else
  415. X        rewind( acf );
  416. X    return;
  417. X}
  418. X
  419. Xendacent()
  420. X
  421. X{
  422. X    if ( acf ) {
  423. X        (void) fclose( acf );
  424. X        acf = NULL;
  425. X    }
  426. X}
  427. X
  428. Xaddr
  429. Xacskip(pp,c)
  430. Xaddr pp;
  431. Xregister c;
  432. X{
  433. X    flexaddr p;
  434. X    register char *cp;
  435. X
  436. X    cp = (char *) pp;
  437. X    while( *cp && *cp != c && (*cp != ':' || c != ',') )
  438. X        ++cp;
  439. X    if ( *cp == ':' && c != ':' ) {
  440. X        *(p.p_cp = cp) = '\0';
  441. X        return( p.p_ap );
  442. X    }
  443. X    if ( *cp ) *cp++ = '\0';
  444. X    p.p_cp = cp;
  445. X    return( p.p_ap );
  446. X}
  447. X
  448. Xstruct account *
  449. Xgetacent()
  450. X
  451. X{
  452. X    flexaddr p, oldp;
  453. X    register struct list *q;
  454. X
  455. X    if (!acf)
  456. X        setacent();
  457. X    zerolist(&acct.ac_groups);
  458. X    zerolist(&acct.ac_classes);
  459. X    zerolist(&acct.ac_sigs);
  460. X#ifdef SENDMAIL
  461. X    zerolist(&acct.ac_aliases);
  462. X#endif
  463. X    if( !(p.p_cp = fgets( (char *)line, BUFSIZ, acf )) )
  464. X        return(NULL);
  465. X    acct.ac_name = p.p_ap;
  466. X    acct.ac_realname = p.p_ap = acskip(p.p_ap, ':');
  467. X    acct.ac_id = p.p_ap = acskip(p.p_ap, ':');
  468. X    p.p_ap = acskip(p.p_ap,':');
  469. X    acct.ac_uid = atoi(p.p_cp);
  470. X    p.p_ap = acskip(p.p_ap,':');
  471. X    acct.ac_gid = atoi(p.p_cp);
  472. X    (void) acskip(p.p_ap,'\n');
  473. X    oldp.p_ap = p.p_ap = acskip(p.p_ap,':');
  474. X    q = &acct.ac_groups;
  475. X    while( *p.p_cp && *p.p_cp != ':' ) {
  476. X        oldp.p_ap = p.p_ap;
  477. X        p.p_ap = acskip(p.p_ap,',');
  478. X        strlistadd(q, oldp.p_cp);
  479. X    }
  480. X    sort_list(q, pstrcmp);
  481. X    p.p_cp++;
  482. X    q = &acct.ac_classes;
  483. X    while( *p.p_cp && *p.p_cp != ':' ) {
  484. X        oldp.p_ap = p.p_ap;
  485. X        p.p_ap = acskip(p.p_ap,',');
  486. X        strlistadd(q, oldp.p_cp);
  487. X    }
  488. X    sort_list(q, pstrcmp);
  489. X    p.p_cp++;
  490. X    q = &acct.ac_sigs;
  491. X    while( *p.p_cp && *p.p_cp != ':' ) {
  492. X        oldp.p_ap = p.p_ap;
  493. X        p.p_ap = acskip(p.p_ap,',');
  494. X        strlistadd(q, oldp.p_cp);
  495. X    }
  496. X    sort_list(q, pstrcmp);
  497. X#ifdef SENDMAIL
  498. X    p.p_cp++;
  499. X    q = &acct.ac_aliases;
  500. X    while( *p.p_cp ) {
  501. X        oldp.p_ap = p.p_ap;
  502. X        p.p_ap = acskip(p.p_ap,',');
  503. X        strlistadd(q, oldp.p_cp);
  504. X    }
  505. X    sort_list(q, pstrcmp);
  506. X#endif
  507. X    return &acct;
  508. X}
  509. X
  510. Xstruct account *
  511. Xgetacuid(uid)
  512. Xint  uid;
  513. X
  514. X{
  515. X    int found, index;
  516. X
  517. X    index = search_list(&AccountList, (char *)&uid, iacctcmp, &found);
  518. X    if (found)
  519. X        return (struct account *) AccountList.l_list[index];
  520. X    return (struct account *) 0;
  521. X}
  522. X
  523. Xstruct account *
  524. Xgetacid(id)
  525. Xchar *id;
  526. X{
  527. X    int indx;
  528. X    struct account *a;
  529. X
  530. X    for (indx=0; indx < AccountList.l_count; indx++) {
  531. X        a = (struct account *) AccountList.l_list[indx];
  532. X        if (eq(a->ac_id, id))
  533. X            return a;
  534. X    }
  535. X    return (struct account *) 0;
  536. X}
  537. X
  538. Xstruct account *
  539. Xgetacnam(name)
  540. Xchar *name;
  541. X{
  542. X    struct account *a;
  543. X    register int indx;
  544. X
  545. X    if (!userexists(name))
  546. X        return (struct account *) 0;
  547. X    for (indx=0; indx < AccountList.l_count; indx++) {
  548. X        a = (struct account *) AccountList.l_list[indx];
  549. X        if (eq(a->ac_name, name))
  550. X            return a;
  551. X    }
  552. X    return (struct account *) 0;
  553. X}
  554. X
  555. X/*
  556. X * Do a simply format check of the accounts file.
  557. X */
  558. Xint
  559. Xacck()
  560. X
  561. X{
  562. X    FILE *f;
  563. X    char b[BUFSIZ];
  564. X
  565. X    f = fopen(ACFILE, "r");
  566. X    if (f == NULL) {
  567. X        err1("can't open %s (read)", ACFILE);
  568. X        return 0;
  569. X    }
  570. X    while (fgets(b, BUFSIZ, f) != NULL) {
  571. X        if (coloncount(b) != 8) {
  572. X            err1("%s: badly formed line", ACFILE);
  573. X            return 0;
  574. X        }
  575. X    }
  576. X    (void) fclose(f);
  577. X    return 1;
  578. X}
  579. @//E*O*F src/account.c//
  580. if test 3317 -ne "`wc -c <'src/account.c'`"; then
  581.     echo shar: error transmitting "'src/account.c'" '(should have been 3317 characters)'
  582. fi
  583. fi # end of overwriting check
  584. echo shar: extracting "'src/account.h'" '(636 characters)'
  585. if test -f 'src/account.h' ; then 
  586.   echo shar: will not over-write existing file "'src/account.h'"
  587. else
  588. sed 's/^X//' >src/account.h <<'@//E*O*F src/account.h//'
  589. Xstruct account {
  590. X    int    ac_uid;
  591. X    int    ac_gid;
  592. X    addr    ac_name;            /* login name */
  593. X    addr    ac_gecos;            /* pw_gecos */
  594. X    addr    ac_realname;            /* in real life... */
  595. X    addr    ac_passwd;            /* encrypted password */
  596. X    addr    ac_id;                /* unqiue id (e.g. SSN) */
  597. X    addr    ac_dir;                /* home directory */
  598. X    addr    ac_shell;            /* login shell */
  599. X    struct     list     ac_groups;
  600. X    struct    list    ac_classes;
  601. X    struct    list    ac_sigs;
  602. X#ifdef SENDMAIL
  603. X    /*
  604. X     * Alias memberships that were not obtained indirectly through
  605. X     * class, sig, or group bindings.
  606. X     */
  607. X    struct    list    ac_aliases;
  608. X#endif
  609. X    struct    lastlog ac_ll;
  610. X};
  611. X
  612. Xstruct account *getacent(), *getacuid(), *getacid(), *getacnam();
  613. @//E*O*F src/account.h//
  614. if test 636 -ne "`wc -c <'src/account.h'`"; then
  615.     echo shar: error transmitting "'src/account.h'" '(should have been 636 characters)'
  616. fi
  617. fi # end of overwriting check
  618. echo shar: extracting "'src/add.c'" '(21617 characters)'
  619. if test -f 'src/add.c' ; then 
  620.   echo shar: will not over-write existing file "'src/add.c'"
  621. else
  622. sed 's/^X//' >src/add.c <<'@//E*O*F src/add.c//'
  623. X/***************************************************************\
  624. X*                                     *
  625. X*     add.c                                *
  626. X*                                     *
  627. X* Routines to add various things, users, groups, classes, etc.  *
  628. X*                                     *
  629. X\***************************************************************/
  630. X
  631. X#include <stdio.h>
  632. X#include <sys/types.h>
  633. X#include <sys/stat.h>
  634. X#include <strings.h>
  635. X#include <ctype.h>
  636. X#include <lastlog.h>
  637. X#include "sysdep.h"
  638. X#include "macros.h"
  639. X#include "mem.h"
  640. X#include "gpa.h"
  641. X#include "lists.h"
  642. X#include "account.h"
  643. X#ifdef SENDMAIL
  644. X#include "alias.h"
  645. X#endif
  646. X#include "class.h"
  647. X#include "groupmap.h"
  648. X#include "job.h"
  649. X#include "range.h"
  650. X#include "sig.h"
  651. X#include "sort.h"
  652. X#include "save.h"
  653. X
  654. X#define DAY    (4*21600)
  655. X
  656. X#ifdef SENDMAIL
  657. Xextern    struct list AliasList, Aliases;
  658. X#endif
  659. Xextern    struct list AccountList, Users, ClassList, Classes, GroupMapList;
  660. Xextern    struct list Groups, RangeList, Ranges, Sigs, SigList, Vigs, Shells;
  661. Xextern    struct list Null_List;
  662. Xextern    int ModBits, validint();
  663. Xextern    addr gethomedir();
  664. Xextern    addr makeusername(), DEF_SHELL;
  665. Xextern    char *crypt(), *mktemp(), *sprintf(), *makepass(), *when();
  666. Xextern    time_t choosedate();
  667. X
  668. Xstatic    char *XXXXXX = "/mcpXXXXXX";
  669. Xstatic    char desc[DESCSIZE+1];
  670. X
  671. Xstatic    char *idl[1] = { "exception" };
  672. Xstatic    char *pwl[3] = { "generate", "none", "unused" };
  673. Xstatic    char *rnl[1];
  674. Xstatic    char *mdl[2] = { "exclusive", "shared" };
  675. X
  676. Xstruct    list idlist = {    1, 1, (addr *)idl };
  677. Xstruct    list pwlist = { 3, 3, (addr *)pwl };
  678. Xstruct    list rnlist = { 1, 1, (addr *)rnl };
  679. Xstruct    list mdlist = { 2, 2, (addr *)mdl };
  680. X
  681. X#ifdef SENDMAIL
  682. X/*
  683. X * Add an alias
  684. X */
  685. Xaddalias(c, v)
  686. Xint c;
  687. Xaddr *v;
  688. X
  689. X{
  690. X    struct alias al;
  691. X    struct account *ac;
  692. X    addr *addressv;
  693. X    int cc;
  694. X    register int i;
  695. X
  696. X    if (c > 2) {
  697. X        err1("%s: too many arguments", (char *)v[0]);
  698. X        return;
  699. X    }
  700. X    if (c != 2) {
  701. X        err1("usage: %s <name>", (char *)v[0]);
  702. X        return;
  703. X    }
  704. X    if (aliasexists((char *)v[1])) {
  705. X        err1("%s: alias exists", (char *)v[1]);
  706. X        return;
  707. X    }
  708. X    addressv = get_gpa(257);
  709. X    GetLine("Addresses: ", 256, &cc, addressv, &Null_List);
  710. X
  711. X    critical();
  712. X    savestr(&al.al_name, (char *)v[1]);
  713. X    zerolist(&al.al_addresses);
  714. X    zerolist(&al.al_classes);
  715. X    zerolist(&al.al_sigs);
  716. X    zerolist(&al.al_groups);
  717. X    for (i=0; i < cc; i++) {
  718. X        strlistadd(&al.al_addresses, (char *)addressv[i]);
  719. X        ac = getacnam((char *)addressv[i]);
  720. X        if (ac)
  721. X            strlistadd(&ac->ac_aliases, (char *)addressv[i]);
  722. X    }
  723. X    sort_list(&al.al_addresses, pstrcmp);
  724. X    strlistadd(&Aliases, (char *)v[1]);
  725. X    genlistadd(&AliasList, (addr)&al, sizeof (struct alias));
  726. X    sort_list(&Aliases, pstrcmp);
  727. X    sort_list(&AliasList, aliascmp);
  728. X    ModBits |= AL;
  729. X    puts("added");
  730. X    non_critical();
  731. X
  732. X    return;
  733. X}
  734. X#endif
  735. X    
  736. X/*
  737. X * Add a class
  738. X */
  739. Xaddclass(c, v)
  740. Xint c;
  741. Xaddr *v;
  742. X
  743. X{
  744. X    struct class cs;
  745. X    struct stat statbuf;
  746. X    char tempf[MEDIUM_BUF], errmsg[LONG_BUF];
  747. X    FILE *f, *fopen();
  748. X    time_t now, time();
  749. X    int tries, i, ch;
  750. X
  751. X    if ( c > 2 ) {
  752. X        err1("%s: too many arguments", (char *)v[0]);
  753. X        return;
  754. X    }
  755. X    if ( c != 2 ) {
  756. X        err1("usage: %s <class>", (char *)v[0]);
  757. X        return;
  758. X    }
  759. X    if (classexists((char *)v[1])) {
  760. X        err1("%s: class exists", (char *)v[1]);
  761. X        return;
  762. X    }
  763. X    if (yesno("Should the class expire? ") == 0)
  764. X        cs.cs_exptime = (time_t) 0;
  765. X    else {
  766. X        (void) time(&now);
  767. X        err("Set the expiration date.");
  768. X        cs.cs_exptime = choosedate(now);
  769. X        (void) printf("Ends %s\n", when(cs.cs_exptime));
  770. X    }
  771. X    (void) strcpy(tempf, TMPDIR);
  772. X    (void) strcat(tempf, XXXXXX);
  773. X    (void) mktemp(tempf);
  774. X    tries = 0;
  775. Xedit_it:
  776. X    tries++;
  777. X    f = fopen(tempf, "w");
  778. X    if (f == NULL) {
  779. X        err1("%s: cannot open (write)", tempf);
  780. X        return;
  781. X    }
  782. X    (void) fprintf(f, "Instructor: \n\n");
  783. X    (void) fprintf(f, "...\n");
  784. X    (void) fclose(f);
  785. Xre_edit:
  786. X    edit(tempf);
  787. X    if (stat(tempf, &statbuf) == -1) {
  788. X        perr(tempf);
  789. X        if (tries < 5) {
  790. X            sleep(2);
  791. X            goto edit_it;
  792. X        }
  793. X        else {
  794. X            err1("%s aborted", (char *)v[0]);
  795. X            (void) unlink(tempf);
  796. X            return;
  797. X        }
  798. X    }
  799. X    if (statbuf.st_size > DESCSIZE) {
  800. X        (void)sprintf(errmsg, "description is %d characters too long",
  801. X            DESCSIZE - statbuf.st_size);
  802. X        err(errmsg);
  803. X        sleep(2);
  804. X        goto re_edit;
  805. X    }
  806. X
  807. X    critical();
  808. X    f = fopen(tempf, "r");
  809. X    if (f == NULL) {
  810. X        err1("%s: cannot open (read)", tempf);
  811. X        non_critical();
  812. X        return;
  813. X    }
  814. X    savestr(&cs.cs_name, (char *)v[1]);
  815. X    i = 0;
  816. X    while ((ch = getc(f)) != EOF)
  817. X        desc[i++] = (char) ch;
  818. X    desc[i] = '\0';
  819. X    cs.cs_dsize = i;
  820. X    savestr(&cs.cs_desc, desc);
  821. X    (void) fclose(f);
  822. X#ifdef SENDMAIL
  823. X    zerolist(&cs.cs_aliases);
  824. X#endif
  825. X    genlistadd(&ClassList, (addr) &cs, sizeof (struct class));
  826. X    strlistadd(&Classes, cs.cs_name);
  827. X    sort_list(&ClassList, classcmp);
  828. X    sort_list(&Classes, pstrcmp);
  829. X    (void) unlink(tempf);
  830. X    ModBits |= CS;
  831. X    puts("added");
  832. X    non_critical();
  833. X
  834. X    return;
  835. X}
  836. X
  837. X/*
  838. X * Add a group
  839. X */
  840. Xaddgroup(c, v)
  841. Xint c;
  842. Xaddr *v;
  843. X
  844. X{
  845. X    struct groupmap gm;
  846. X    char prompt[SHORT_BUF];
  847. X    addr *gidv;
  848. X    int cc, gid;
  849. X
  850. X    if ( c > 2 ) {
  851. X        err1("%s: too many arguments", (char *)v[0]);
  852. X        return;
  853. X    }
  854. X    if (c != 2) {
  855. X        err1("usage: %s <name>", (char *)v[0]);
  856. X        return;
  857. X    }
  858. X    if (groupexists((char *)v[1])) {
  859. X        err1("%s: group exists", (char *)v[1]);
  860. X        return;
  861. X    }
  862. X    gm.gm_gid = nextgid();
  863. X    (void) sprintf(prompt, "Gid [%d]: ", gm.gm_gid);
  864. X    gidv = get_gpa(2);
  865. X    do {
  866. X        GetLine(prompt, 1, &cc, gidv, &Null_List);
  867. X        if (cc) {
  868. X        if (!validint((char *)*gidv)) {
  869. X            err1("%s makes no sense to me", (char *)*gidv);
  870. X            continue;
  871. X        }
  872. X        gid = atoi((char *)*gidv);
  873. X        if (gidexists(gid))
  874. X            err("that gid is taken");
  875. X        else {
  876. X            gm.gm_gid = gid;
  877. X            break;
  878. X        }
  879. X        }
  880. X        else
  881. X            break;
  882. X    } while (clear_gpa(gidv, 2));
  883. X
  884. X    critical();
  885. X    savestr(&gm.gm_name, (char *)v[1]);
  886. X    savestr(&gm.gm_passwd, "*");
  887. X    zerolist(&gm.gm_mem);
  888. X#ifdef SENDMAIL
  889. X    zerolist(&gm.gm_aliases);
  890. X#endif
  891. X    genlistadd(&GroupMapList, (addr) &gm, sizeof (struct groupmap));
  892. X    sort_list(&GroupMapList, gmapcmp);
  893. X    strlistadd(&Groups, gm.gm_name);
  894. X    sort_list(&Groups, pstrcmp);
  895. X    ModBits |= GR;
  896. X    puts("added");
  897. X    non_critical();
  898. X
  899. X    return;
  900. X}
  901. X
  902. Xint nextgid()
  903. X
  904. X{
  905. X    register int i, next = 0;
  906. X    struct groupmap *gm;
  907. X
  908. X    for (i=0; i<GroupMapList.l_count; i++) {
  909. X        gm = (struct groupmap *) GroupMapList.l_list[i];
  910. X        if (gm->gm_gid > next)
  911. X            return next;
  912. X        /*
  913. X         * Since gid's may be shared (gag) by two or more group names
  914. X         * the seemingly obvious next++ actually must be...
  915. X         */
  916. X        next = gm->gm_gid + 1;
  917. X    }
  918. X    return next;
  919. X}
  920. X
  921. X/*
  922. X * Add a range
  923. X */
  924. Xaddrange(c, v)
  925. Xint c;
  926. Xaddr *v;
  927. X
  928. X{
  929. X    struct range r, *rg;
  930. X    char prompt[SHORT_BUF];
  931. X    addr *fromv, *tov, *modev;
  932. X    int cc, indx;
  933. X
  934. X    if ( c > 2 ) {
  935. X        err1("%s: too many arguments", (char *)v[0]);
  936. X        return;
  937. X    }
  938. X    if (c != 2) {
  939. X        err1("usage: %s <name>", (char *)v[0]);
  940. X        return;
  941. X    }
  942. X    if (!groupexists((char *)v[1])) {
  943. X        err1("%s: no such group", (char *)v[1]);
  944. X        return;
  945. X    }
  946. X    (void) strcpy(prompt, "From: ");
  947. X    fromv = get_gpa(2);
  948. X    do {
  949. X        GetLine(prompt, 1, &cc, fromv, &Null_List);
  950. X        if (cc && !validint((char *)*fromv)) {
  951. X            cc = 0;
  952. X            continue;
  953. X        }
  954. X    } while (cc == 0 && clear_gpa(fromv, 2));
  955. X
  956. X    (void) strcpy(prompt, "To  : ");
  957. X    tov = get_gpa(2);
  958. X    do {
  959. X        GetLine(prompt, 1, &cc, tov, &Null_List);
  960. X        if (cc && !validint((char *)*tov)) {
  961. X            cc = 0;
  962. X            continue;
  963. X        }
  964. X    } while (cc == 0 && clear_gpa(tov, 2));
  965. X
  966. X    (void) strcpy(prompt, "Mode: ");
  967. X    modev = get_gpa(2);
  968. X    do {
  969. X        GetLine(prompt, 1, &cc, modev, &mdlist);
  970. X    } while (cc == 0 && clear_gpa(modev, 2));
  971. X
  972. X    if (eq(*modev, "shared"))
  973. X        r.rg_mode = RG_SHARED;
  974. X    else if (eq(*modev, "exclusive"))
  975. X        r.rg_mode = RG_EXCLUSIVE;
  976. X    else {
  977. X        err1("%s: unknown mode", (char *)*modev);
  978. X        return;
  979. X    }
  980. X    r.rg_from = atoi((char *)*fromv);
  981. X    r.rg_to = atoi((char *)*tov);
  982. X
  983. X    for (indx=0; indx < RangeList.l_count; indx++) {
  984. X        rg = (struct range *) RangeList.l_list[indx];
  985. X        if (rg->rg_mode == RG_SHARED && r.rg_mode == RG_SHARED)
  986. X            continue;
  987. X        if (INRANGE(r.rg_from, rg->rg_from, rg->rg_to)) {
  988. X            err1("conflicts with range of group %s", rg->rg_name);
  989. X            return;
  990. X        }
  991. X        if (INRANGE(r.rg_to, rg->rg_from, rg->rg_to)) {
  992. X            err1("conflicts with range of group %s", rg->rg_name);
  993. X            return;
  994. X        }
  995. X    }
  996. X
  997. X    critical();
  998. X    savestr(&r.rg_name, (char *)v[1]);
  999. X    genlistadd(&RangeList, (addr) &r, sizeof (struct range));
  1000. X    sort_list(&RangeList, rangecmp);
  1001. X    strlistadd(&Ranges, (char *)v[1]);
  1002. X    sort_list(&Ranges, pstrcmp);
  1003. X    ModBits |= RG;
  1004. X    puts("added");
  1005. X    non_critical();
  1006. X    return;
  1007. X}
  1008. X
  1009. X/*
  1010. X * Add a sig
  1011. X */
  1012. Xaddsig(c, v)
  1013. Xint c;
  1014. Xaddr *v;
  1015. X
  1016. X{
  1017. X    struct sig sg;
  1018. X    struct stat statbuf;
  1019. X    FILE *f, *fopen();
  1020. X    time_t now, time();
  1021. X    int tries, i, ch;
  1022. X    char tempf[SHORT_BUF+1], errmsg[LONG_BUF];
  1023. X
  1024. X    if ( c > 2 ) {
  1025. X        err1("%s: too many arguments", (char *)v[0]);
  1026. X        return;
  1027. X    }
  1028. X    if ( c != 2 ) {
  1029. X        err1("usage: %s <name>", (char *)v[0]);
  1030. X        return;
  1031. X    }
  1032. X    if (sigexists((char *)v[1])) {
  1033. X        err1("%s: sig exists", (char *)v[1]);
  1034. X        return;
  1035. X    }
  1036. X    if (yesno("Should the sig expire? ") == 0)
  1037. X        sg.sg_exptime = (time_t) 0;
  1038. X    else {
  1039. X        (void) time(&now);
  1040. X        err("Set the expiration date.");
  1041. X        sg.sg_exptime = choosedate(now);
  1042. X        (void) printf("Sig ends %s\n", when(sg.sg_exptime));
  1043. X    }
  1044. X    (void) strcpy(tempf, TMPDIR);
  1045. X    (void) strcat(tempf, XXXXXX);
  1046. X    (void) mktemp(tempf);
  1047. X    tries = 0;
  1048. Xedit_it:
  1049. X    tries++;
  1050. X    f = fopen(tempf, "w");
  1051. X    if (f == NULL) {
  1052. X        err1("%s: cannot open (write)", tempf);
  1053. X        return;
  1054. X    }
  1055. X    (void) fprintf(f, "Guru: \n\n");
  1056. X    (void) fprintf(f, "...\n");
  1057. X    (void) fclose(f);
  1058. Xre_edit:
  1059. X    edit(tempf);
  1060. X    if (stat(tempf, &statbuf) == -1) {
  1061. X        perr(tempf);
  1062. X        if (tries < 5) {
  1063. X            sleep(2);
  1064. X            goto edit_it;
  1065. X        }
  1066. X        else {
  1067. X            err1("%s aborted", (char *)v[0]);
  1068. X            (void) unlink(tempf);
  1069. X            return;
  1070. X        }
  1071. X    }
  1072. X    if (statbuf.st_size > DESCSIZE) {
  1073. X        (void) sprintf(errmsg, 
  1074. X                "description is %d characters too long",
  1075. X                DESCSIZE - statbuf.st_size);
  1076. X        err(errmsg);
  1077. X        sleep(2);
  1078. X        goto re_edit;
  1079. X    }
  1080. X
  1081. X    critical();
  1082. X    f = fopen(tempf, "r");
  1083. X    if (f == NULL) {
  1084. X        err1("%s: cannot open (read)", tempf);
  1085. X        non_critical();
  1086. X        return;
  1087. X    }
  1088. X    savestr(&sg.sg_name, (char *)v[1]);
  1089. X    i = 0;
  1090. X    while ((ch = getc(f)) != EOF)
  1091. X        desc[i++] = (char) ch;
  1092. X    desc[i] = '\0';
  1093. X    sg.sg_dsize = i;
  1094. X    savestr(&sg.sg_desc, desc);
  1095. X    (void) fclose(f);
  1096. X#ifdef SENDMAIL
  1097. X    zerolist(&sg.sg_aliases);
  1098. X#endif
  1099. X    genlistadd(&SigList, (addr) &sg, sizeof (struct sig));
  1100. X    strlistadd(&Sigs, sg.sg_name);
  1101. X    sort_list(&SigList, sigcmp);
  1102. X    sort_list(&Sigs, pstrcmp);
  1103. X    (void) unlink(tempf);
  1104. X    ModBits |= SG;
  1105. X    puts("added");
  1106. X    non_critical();
  1107. X
  1108. X    return;
  1109. X}
  1110. X
  1111. X#ifdef SENDMAIL
  1112. Xaddtoalias(c, v)
  1113. Xint c;
  1114. Xaddr *v;
  1115. X
  1116. X{
  1117. X    struct alias *al;
  1118. X    struct account *ac;
  1119. X    addr *addressv;
  1120. X    int cc, added = 0, notes = 0;
  1121. X    register int indx;
  1122. X
  1123. X    if (c > 2) {
  1124. X        err1("%s: too many arguments", (char *)v[0]);
  1125. X        return;
  1126. X    }
  1127. X    if (c != 2) {
  1128. X        err1("usage: %s <alias>", (char *)v[0]);
  1129. X        return;
  1130. X    }
  1131. X    al = getalnam((char *)v[1]);
  1132. X    if (!al) {
  1133. X        err1("%s: no such alias", (char *)v[1]);
  1134. X        return;
  1135. X    }
  1136. X
  1137. X    addressv = get_gpa(65);
  1138. X    GetLine("Addresses: ", 64, &cc, addressv, &Null_List);
  1139. X    if (cc == 0) {
  1140. X        err("no change");
  1141. X        return;
  1142. X    }
  1143. X
  1144. X    critical();
  1145. X    for (indx=0; indx < cc; indx++) {
  1146. X        ac = getacnam((char *)addressv[indx]);
  1147. X        if (ac) {
  1148. X        if (!instrlist(&ac->ac_aliases, (char *)v[1])) {
  1149. X            strlistadd(&ac->ac_aliases, (char *)v[1]);
  1150. X            sort_list(&ac->ac_aliases, pstrcmp);
  1151. X            ModBits |= AC;
  1152. X        }
  1153. X        else {
  1154. X            err1("%s: already in alias", (char *)ac->ac_name);
  1155. X            continue;
  1156. X        }
  1157. X        }
  1158. X        if (!instrlist(&al->al_addresses, (char *)addressv[indx])) {
  1159. X        strlistadd(&al->al_addresses, (char *)addressv[indx]);
  1160. X        added++;
  1161. X        }
  1162. X        else if (!ac)
  1163. X        err1("%s: already in alias", (char *)addressv[indx]);
  1164. X        else {
  1165. X        err1("%s: unique membership noted", (char *)ac->ac_name);
  1166. X        notes++;
  1167. X        }
  1168. X    }
  1169. X    if (added) {
  1170. X        sort_list(&al->al_addresses, pstrcmp);
  1171. X        ModBits |= AL;
  1172. X        (void) printf("%d added\n", added);
  1173. X    }
  1174. X    else if (!notes)
  1175. X        err("no change");
  1176. X    non_critical();
  1177. X
  1178. X    return;
  1179. X}
  1180. X#endif
  1181. X
  1182. Xaddtoclass(c, v)
  1183. Xint c;
  1184. Xaddr *v;
  1185. X
  1186. X{
  1187. X    struct account *ac;
  1188. X    struct class *cs;
  1189. X    addr *userv;
  1190. X    int cc, added = 0;
  1191. X    register int indx;
  1192. X#ifdef SENDMAIL
  1193. X    struct alias *al;
  1194. X    register int j;
  1195. X#endif
  1196. X
  1197. X    if ( c > 2 ) {
  1198. X        err1("%s: too many arguments", (char *)v[0]);
  1199. X        return;
  1200. X    }
  1201. X    if (c != 2) {
  1202. X        err1("usage: %s <class>", (char *)v[0]);
  1203. X        return;
  1204. X    }
  1205. X    cs = getcsnam((char *)v[1]);
  1206. X    if (!cs) {
  1207. X        err1("%s: no such class", (char *)v[1]);
  1208. X        return;
  1209. X    }
  1210. X    userv = get_gpa(65);
  1211. X    GetLine("Users: ", 64, &cc, userv, &Users);
  1212. X    if (cc == 0) {
  1213. X        err("no change");
  1214. X        return;
  1215. X    }
  1216. X
  1217. X    critical();
  1218. X    for (indx=0; indx < cc; indx++) {
  1219. X        ac = getacnam((char *)userv[indx]);
  1220. X        if (!ac) {
  1221. X            err1("%s: no such user", (char *)userv[indx]);
  1222. X            continue;
  1223. X        }
  1224. X        if (instrlist(&ac->ac_classes, (char *)v[1])) {
  1225. X            err1("%s: already is in class\n",
  1226. X                (char *)userv[indx]);
  1227. X            continue;
  1228. X        }
  1229. X        strlistadd(&ac->ac_classes, (char *)v[1]);
  1230. X        sort_list(&ac->ac_classes, pstrcmp);
  1231. X#ifdef SENDMAIL
  1232. X        for (j=0; j < cs->cs_aliases.l_count; j++) {
  1233. X            al = getalnam((char *)cs->cs_aliases.l_list[j]);
  1234. X            if (!al) continue;    /* trouble */
  1235. X            if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) {
  1236. X            strlistadd(&al->al_addresses, (char *)ac->ac_name);
  1237. X            sort_list(&al->al_addresses, pstrcmp);
  1238. X            ModBits |= AL;
  1239. X            }
  1240. X        }
  1241. X#endif
  1242. X        added++;
  1243. X    }
  1244. X    if (added) {
  1245. X        ModBits |= AC;
  1246. X        (void) printf("%d added\n", added);
  1247. X    }
  1248. X    else
  1249. X        err("no change");
  1250. X    non_critical();
  1251. X
  1252. X    return;
  1253. X}
  1254. X
  1255. Xaddtogroup(c, v)
  1256. Xint c;
  1257. Xaddr *v;
  1258. X
  1259. X{
  1260. X    struct account *ac;
  1261. X    struct groupmap *gm;
  1262. X    addr *userv;
  1263. X    int cc, added = 0;
  1264. X    register int indx;
  1265. X#ifdef SENDMAIL
  1266. X    struct alias *al;
  1267. X    register int j;
  1268. X#endif
  1269. X
  1270. X    if ( c > 2 ) {
  1271. X        err1("%s: too many arguments", (char *)v[0]);
  1272. X        return;
  1273. X    }
  1274. X    if (c != 2) {
  1275. X        err1("usage: %s <group>", (char *)v[0]);
  1276. X        return;
  1277. X    }
  1278. X    gm = getgmnam((char *)v[1]);
  1279. X    if (!gm) {
  1280. X        err1("%s: no such group", (char *)v[1]);
  1281. X        return;
  1282. X    }
  1283. X    userv = get_gpa(65);
  1284. X    GetLine("Users: ", 64, &cc, userv, &Users);
  1285. X    if (cc == 0) {
  1286. X        err("no change");
  1287. X        return;
  1288. X    }
  1289. X
  1290. X    critical();
  1291. X    for (indx=0; indx < cc; indx++) {
  1292. X        if (instrlist(&gm->gm_mem, (char *)userv[indx])) {
  1293. X            err1("%s: is in group", (char *)userv[indx]);
  1294. X            continue;
  1295. X        }
  1296. X        ac = getacnam((char *)userv[indx]);
  1297. X        if (!ac) {
  1298. X            err1("%s: no such user", (char *)userv[indx]);
  1299. X            continue;
  1300. X        }
  1301. X        strlistadd(&ac->ac_groups, (char *)v[1]);
  1302. X        strlistadd(&gm->gm_mem, (char *)userv[indx]);
  1303. X        sort_list(&ac->ac_groups, pstrcmp);
  1304. X#ifdef SENDMAIL
  1305. X        for (j=0; j < gm->gm_aliases.l_count; j++) {
  1306. X            al = getalnam((char *)gm->gm_aliases.l_list[j]);
  1307. X            if (!al) continue;    /* trouble */
  1308. X            if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) {
  1309. X            strlistadd(&al->al_addresses, (char *)ac->ac_name);
  1310. X            sort_list(&al->al_addresses, pstrcmp);
  1311. X            ModBits |= AL;
  1312. X            }
  1313. X        }
  1314. X#endif
  1315. X        added++;
  1316. X    }
  1317. X    if (added) {
  1318. X        ModBits |= AC|GR;
  1319. X        sort_list(&gm->gm_mem, pstrcmp);
  1320. X        (void) printf("%d added\n", added);
  1321. X    }
  1322. X    else
  1323. X        err("no change");
  1324. X    non_critical();
  1325. X
  1326. X    return;
  1327. X}
  1328. X
  1329. Xaddtosig(c, v)
  1330. Xint c;
  1331. Xaddr *v;
  1332. X
  1333. X{
  1334. X    struct account *ac;
  1335. X    struct sig *sg;
  1336. X    addr *userv;
  1337. X    int cc, added = 0;
  1338. X    register int indx;
  1339. X#ifdef SENDMAIL
  1340. X    struct alias *al;
  1341. X    register int j;
  1342. X#endif
  1343. X
  1344. X    if ( c > 2 ) {
  1345. X        err1("%s: too many arguments", (char *)v[0]);
  1346. X        return;
  1347. X    }
  1348. X    if (c != 2) {
  1349. X        err1("usage: %s <sig>", (char *)v[0]);
  1350. X        return;
  1351. X    }
  1352. X    sg = getsgnam((char *)v[1]);
  1353. X    if (!sg) {
  1354. X        err1("%s: no such sig", (char *)v[1]);
  1355. X        return;
  1356. X    }
  1357. X    userv = get_gpa(65);
  1358. X    GetLine("Users: ", 64, &cc, userv, &Users);
  1359. X    if (cc == 0) {
  1360. X        err("no change");
  1361. X        return;
  1362. X    }
  1363. X
  1364. X    critical();
  1365. X
  1366. X    for (indx=0; indx < cc; indx++) {
  1367. X        ac = getacnam((char *)userv[indx]);
  1368. X        if (!ac) {
  1369. X            err1("%s: no such user", (char *)userv[indx]);
  1370. X            continue;
  1371. X        }
  1372. X        if (instrlist(&ac->ac_sigs, (char *)v[1])) {
  1373. X            err1("%s: already is in sig", (char *)userv[indx]);
  1374. X            continue;
  1375. X        }
  1376. X        strlistadd(&ac->ac_sigs, (char *)v[1]);
  1377. X        sort_list(&ac->ac_sigs, pstrcmp);
  1378. X#ifdef SENDMAIL
  1379. X        for (j=0; j < sg->sg_aliases.l_count; j++) {
  1380. X            al = getalnam((char *)sg->sg_aliases.l_list[j]);
  1381. X            if (!al) continue;    /* trouble */
  1382. X            if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) {
  1383. X            strlistadd(&al->al_addresses, (char *)ac->ac_name);
  1384. X            sort_list(&al->al_addresses, pstrcmp);
  1385. X            ModBits |= AL;
  1386. X            }
  1387. X        }
  1388. X#endif
  1389. X        added++;
  1390. X    }
  1391. X    if (added) {
  1392. X        ModBits |= AC;
  1393. X        (void) printf("%d added\n", added);
  1394. X    }
  1395. X    else
  1396. X        err("no change");
  1397. X    non_critical();
  1398. X
  1399. X    return;
  1400. X}
  1401. X
  1402. Xadduser(c, v)
  1403. Xint c;
  1404. Xaddr *v;
  1405. X
  1406. X{
  1407. X    struct account *aa;
  1408. X    struct groupmap *gm;
  1409. X    addr *realnamev, *idv, *passwdv, *groupv, *uidv, *shellv;
  1410. X    addr username, def_dir, *dirv;
  1411. X    addr shell, dir;
  1412. X    addr password[SHORT_BUF];
  1413. X    char prompt[MEDIUM_BUF], prompt2[MEDIUM_BUF], *salt;
  1414. X    int cc, uid, n;
  1415. X    addr_t cap[SHORT_BUF];
  1416. X
  1417. X    if ( c > 2 ) {
  1418. X        err1("%s: too many arguments", (char *)v[0]);
  1419. X        return;
  1420. X    }
  1421. X    if (c > 1 && userexists((char *)v[1])) {
  1422. X        err1("%s: user exists", (char *) v[1]);
  1423. X        return;
  1424. X    }
  1425. X    if (c > 1) {
  1426. X        (void) strcpy((char *)cap, (char *)v[1]);
  1427. X        capitalize((char *)cap);
  1428. X        rnlist.l_count = 1;
  1429. X        rnlist.l_list[0] = cap;
  1430. X    }
  1431. X    else
  1432. X        rnlist.l_count = 0;
  1433. X    
  1434. X    realnamev = get_gpa(17);
  1435. X    do {
  1436. X        GetLine("Real Name: ", 16, &cc, realnamev, &rnlist);
  1437. X    } while (cc == 0 && clear_gpa(realnamev, 17));
  1438. X
  1439. X    /*
  1440. X     * If we were handed a username, take it.  If not, we must manufacture
  1441. X     * one from the Real Name.
  1442. X     */
  1443. X    if (c > 1)
  1444. X        username = v[1];
  1445. X    else {
  1446. X        username = makeusername(cc, realnamev);
  1447. X        (void) printf("login name is \"%s\"\n", username);
  1448. X    }
  1449. X
  1450. X    /*
  1451. X     * Unique identification, like SSN
  1452. X     */
  1453. X    idv = get_gpa(2);
  1454. X    do {
  1455. X        GetLine("Id: ", 1, &cc, idv, &idlist);
  1456. X    } while (cc == 0 && clear_gpa(idv, 2));
  1457. X    if (!eq(*idv, "exception") && (aa = getacid((char *)*idv))) {
  1458. X        (void) sprintf(prompt, "%s shares that id.  continue? [no] ",
  1459. X            (char *)aa->ac_name);
  1460. X        if (no(prompt))
  1461. X            return;
  1462. X    }
  1463. X
  1464. X    /*
  1465. X     * Give the user a password
  1466. X     */
  1467. X    (void) sprintf(prompt, "Password [%s]: ", *idv);
  1468. X    passwdv = get_gpa(2);
  1469. X    GetLine(prompt, 1, &cc, passwdv, &pwlist);
  1470. X    if (cc)
  1471. X        if (eq(*passwdv, "none"))
  1472. X            (void) strcpy((char *)password, "");
  1473. X        else if (eq(*passwdv, "unused"))
  1474. X            (void) strcpy((char *)password, "*");
  1475. X        else if (eq(*passwdv, "generate")) {
  1476. X            (void) strcpy((char *)password, makepass());
  1477. X            (void) printf("password is \"%s\"\n", password);
  1478. X        }
  1479. X        else {
  1480. X            salt = CRYPT_SALT;
  1481. X            (void) strcpy((char *)password,
  1482. X                    crypt((char *)*passwdv, salt));
  1483. X        }
  1484. X    else {
  1485. X        salt = CRYPT_SALT;
  1486. X        (void) strcpy((char *)password, crypt((char *)*idv, salt));
  1487. X    }
  1488. X
  1489. X    (void) sprintf(prompt, "Group [%s]: ", DEF_GROUP);
  1490. X    groupv = get_gpa(2);
  1491. X    do {
  1492. X        GetLine(prompt, 1, &cc, groupv, &Groups);
  1493. X        if (cc) {
  1494. X            gm = getgmnam((char *)*groupv);
  1495. X            if (!gm)
  1496. X                err1("%s: no such group", (char *)*groupv);
  1497. X            else
  1498. X                break;
  1499. X        }
  1500. X        else {
  1501. X            gm = getgmnam(DEF_GROUP);
  1502. X            if (!gm) {
  1503. X                err1("%s: no such group", DEF_GROUP);
  1504. X                continue;
  1505. X            }
  1506. X            break;
  1507. X        }
  1508. X    } while (clear_gpa(groupv, 2));
  1509. X
  1510. X    uid = findnextuid(gm->gm_name);
  1511. X    if (uid == NOMORE) {
  1512. X        err1("no more free uids for group %s!",
  1513. X            gm->gm_name);
  1514. X        return;
  1515. X    }
  1516. X    (void) sprintf(prompt, "Uid [%d]: ", uid);
  1517. X    uidv = get_gpa(2);
  1518. X    do {
  1519. X        GetLine(prompt, 1, &cc, uidv, &Null_List);
  1520. X        if (cc) {
  1521. X        if (!validint((char *)*uidv)) {
  1522. X            err1("%s makes no sense to me", (char *)*uidv);
  1523. X            continue;
  1524. X        }
  1525. X        n = atoi((char *)*uidv);
  1526. X        aa = getacuid(n);
  1527. X        if (aa) {
  1528. X            (void) sprintf(prompt2,
  1529. X                    "%s shares that uid, use anyway? ",
  1530. X                    aa->ac_name);
  1531. X            if (yesno(prompt2)) {
  1532. X            uid = n;
  1533. X            break;
  1534. X            }
  1535. X        }
  1536. X        else {
  1537. X            uid = n;
  1538. X            break;
  1539. X        }
  1540. X        }
  1541. X        else
  1542. X            break;
  1543. X    } while (clear_gpa(uidv, 2));
  1544. X
  1545. X    /*
  1546. X     * Shell
  1547. X     */
  1548. X    (void) sprintf(prompt, "Shell [%s]: ", DEF_SHELL);
  1549. X    shellv = get_gpa(2);
  1550. X    GetLine(prompt, 1, &cc, shellv, &Shells);
  1551. X    shell = (cc == 0) ? DEF_SHELL : *shellv;
  1552. X
  1553. X    /*
  1554. X     * Home directory.
  1555. X     */
  1556. X    def_dir = gethomedir((char *)username, gm->gm_name);
  1557. X    (void) sprintf(prompt, "Home [%s]: ", def_dir);
  1558. X    dirv = get_gpa(2);
  1559. X    GetFilenames(prompt, 1, &cc, dirv);
  1560. X    dir = (cc == 0) ? def_dir : *dirv;
  1561. X
  1562. X    addu(uid, gm->gm_gid, username, glob(realnamev),
  1563. X        (addr)password, *idv, dir, shell);
  1564. X
  1565. X#ifndef DOFILES
  1566. X    err("Don't forget to create this user's directory!");
  1567. X#endif
  1568. X    puts("added");
  1569. X    return;
  1570. X}
  1571. X
  1572. Xaddvig(c, v)
  1573. Xint c;
  1574. Xaddr *v;
  1575. X
  1576. X{
  1577. X    if ( c > 2 ) {
  1578. X        err1("%s: too many arguments", (char *)v[0]);
  1579. X        return;
  1580. X    }
  1581. X    if (c != 2) {
  1582. X        err1("usage: %s <name>", (char *)v[0]);
  1583. X        return;
  1584. X    }
  1585. X    if (!groupexists((char *)v[1])) {
  1586. X        err1("%s: no such group", (char *)v[1]);
  1587. X        return;
  1588. X    }
  1589. X
  1590. X    critical();
  1591. X    strlistadd(&Vigs, (char *)v[1]);
  1592. X    sort_list(&Vigs, pstrcmp);
  1593. X    ModBits |= VG;
  1594. X    puts("added");
  1595. X    non_critical();
  1596. X
  1597. X    return;
  1598. X}
  1599. X
  1600. X
  1601. Xaddu(uid, gid, username, realname, password, id, dir, shell)
  1602. Xint uid, gid;
  1603. Xaddr username, realname, password, id, dir, shell;
  1604. X
  1605. X{
  1606. X    struct account ac;
  1607. X#ifdef SENDMAIL
  1608. X    struct groupmap *gm;
  1609. X    struct alias *al;
  1610. X    register int j;
  1611. X#endif
  1612. X#ifdef DOFILES
  1613. X    int zero = 0;
  1614. X#endif
  1615. X
  1616. X    critical();
  1617. X#ifdef SENDMAIL
  1618. X    zerolist(&ac.ac_aliases);
  1619. X#endif
  1620. X    zerolist(&ac.ac_groups);
  1621. X    zerolist(&ac.ac_sigs);        zerolist(&ac.ac_classes);
  1622. X    ac.ac_uid = uid;
  1623. X    ac.ac_gid = gid;
  1624. X    savestr((char **)&ac.ac_name, (char *)username);
  1625. X    savestr((char **)&ac.ac_realname, (char *)realname);
  1626. X    savestr((char **)&ac.ac_gecos, (char *)realname);
  1627. X    savestr((char **)&ac.ac_passwd, (char *)password);
  1628. X    savestr((char **)&ac.ac_id, (char *)id);
  1629. X    savestr((char **)&ac.ac_dir, (char *)dir);
  1630. X    savestr((char **)&ac.ac_shell, (char *)shell);
  1631. X    ac.ac_ll.ll_time = (time_t) 0;
  1632. X    (void) strncpy(ac.ac_ll.ll_line, "", sizeof ac.ac_ll.ll_line);
  1633. X    (void) strncpy(ac.ac_ll.ll_host, "", sizeof ac.ac_ll.ll_host);
  1634. X    genlistadd(&AccountList, (addr) &ac, sizeof (struct account));
  1635. X    sort_list(&AccountList, acctcmp);
  1636. X    strlistadd(&Users, (char *)ac.ac_name);
  1637. X    sort_list(&Users, pstrcmp);
  1638. X#ifdef DOFILES
  1639. X    add_job(JB_MKDIR, ac.ac_dir, (addr)&ac.ac_uid,
  1640. X        (addr)&zero);
  1641. X#endif
  1642. X    add_job(JB_LASTLOG, (addr) &ac.ac_uid,
  1643. X        (addr)&ac.ac_ll, NIL);
  1644. X    ModBits |= (AC|PW);
  1645. X#ifdef SENDMAIL
  1646. X    gm = getgmgid(ac.ac_gid);
  1647. X    for (j=0; j < gm->gm_aliases.l_count; j++) {
  1648. X        al = getalnam((char *)gm->gm_aliases.l_list[j]);
  1649. X        if (!al) continue;    /* trouble */
  1650. X        if (!instrlist(&al->al_addresses, (char *)ac.ac_name)) {
  1651. X        strlistadd(&al->al_addresses, (char *)ac.ac_name);
  1652. X        sort_list(&al->al_addresses, pstrcmp);
  1653. X        ModBits |= AL;
  1654. X        }
  1655. X    }
  1656. X#endif
  1657. X    non_critical();
  1658. X
  1659. X    return;
  1660. X}
  1661. @//E*O*F src/add.c//
  1662. if test 21617 -ne "`wc -c <'src/add.c'`"; then
  1663.     echo shar: error transmitting "'src/add.c'" '(should have been 21617 characters)'
  1664. fi
  1665. fi # end of overwriting check
  1666. echo shar: extracting "'src/alias.c'" '(3382 characters)'
  1667. if test -f 'src/alias.c' ; then 
  1668.   echo shar: will not over-write existing file "'src/alias.c'"
  1669. else
  1670. sed 's/^X//' >src/alias.c <<'@//E*O*F src/alias.c//'
  1671. X#include <stdio.h>
  1672. X#include <ctype.h>
  1673. X#include "sysdep.h"
  1674. X
  1675. X#ifdef SENDMAIL
  1676. X#include "mem.h"
  1677. X#include "macros.h"
  1678. X#include "lists.h"
  1679. X#include "alias.h"
  1680. X#include "sort.h"
  1681. X
  1682. Xextern    addr acskip();
  1683. X
  1684. X#define    alskip acskip
  1685. X
  1686. Xextern    struct list AliasList;
  1687. X
  1688. Xstatic struct alias aka;
  1689. Xstatic FILE *alf = NULL;
  1690. Xstatic FILE *bindf = NULL;
  1691. Xstatic char line[BUFSIZ];
  1692. X
  1693. Xsetalent()
  1694. X
  1695. X{
  1696. X    if (alf == NULL) {
  1697. X        alf = fopen(ALIASFILE, "r");
  1698. X        if (alf == NULL) {
  1699. X            perr(ALIASFILE);
  1700. X            goodbye(1);
  1701. X        }
  1702. X    }
  1703. X    rewind(alf);
  1704. X    if (bindf == NULL) {
  1705. X        bindf = fopen(ALBIND, "r");
  1706. X        if (bindf == NULL) {
  1707. X            perr(ALBIND);
  1708. X            goodbye(1);
  1709. X        }
  1710. X    }
  1711. X    rewind(bindf);
  1712. X    return;
  1713. X}
  1714. X
  1715. Xendalent()
  1716. X
  1717. X{
  1718. X    if (alf != NULL) {
  1719. X        (void) fclose(alf);
  1720. X        alf = NULL;
  1721. X    }
  1722. X    if (bindf != NULL) {
  1723. X        (void) fclose(bindf);
  1724. X        bindf = NULL;
  1725. X    }
  1726. X    return;
  1727. X}
  1728. X
  1729. Xstatic
  1730. Xint getch()
  1731. X
  1732. X{
  1733. X    int c;
  1734. X
  1735. X    for (;;) {
  1736. X        c = getc(alf);
  1737. X        if (c == '#') {
  1738. X            while ((c = getc(alf)) != '\n' && c != EOF)
  1739. X                ;
  1740. X            return c;
  1741. X        }
  1742. X        break;
  1743. X    }
  1744. X    return c;
  1745. X}
  1746. X
  1747. Xstruct alias *
  1748. Xgetalent()
  1749. X
  1750. X{
  1751. X    int c;
  1752. X    register int i = 0;
  1753. X    register struct list *q;
  1754. X    static char name[MEDIUM_BUF], address[LONG_BUF];
  1755. X    flexaddr p, oldp;
  1756. X    int quoteopen = 0;
  1757. X
  1758. X    zerolist(&aka.al_addresses);
  1759. X    zerolist(&aka.al_groups);
  1760. X    zerolist(&aka.al_classes);
  1761. X    zerolist(&aka.al_sigs);
  1762. X    aka.al_name = (char *)0;
  1763. X    while ((c = getch()) != EOF) {
  1764. X        if (c == '\n')
  1765. X            if (aka.al_name) {
  1766. X                c = getch();
  1767. X                if (!isspace(c) || c == '\n') {
  1768. X                    (void) ungetc(c, alf);
  1769. X                    break;
  1770. X                }
  1771. X                else
  1772. X                    continue;
  1773. X            }
  1774. X            else
  1775. X                continue;
  1776. X        if (isspace(c) && !quoteopen)
  1777. X            continue;
  1778. X        if (c == '"')
  1779. X            quoteopen = !quoteopen;
  1780. X        if (!aka.al_name) {
  1781. X            if (c == ':') {
  1782. X                name[i] = '\0';
  1783. X                aka.al_name = name;
  1784. X                i = 0;
  1785. X            }
  1786. X            else
  1787. X                name[i++] = (char) c;
  1788. X            continue;
  1789. X        }
  1790. X        if (c == ',' && i != 0) {
  1791. X            address[i] = '\0';
  1792. X            strlistadd(&aka.al_addresses, address);
  1793. X            i = 0;
  1794. X        }
  1795. X        else if (c == ',' && i == 0)
  1796. X            continue;
  1797. X        else
  1798. X            address[i++] = (char) c;
  1799. X    }
  1800. X    if (!aka.al_name)
  1801. X        return (struct alias *) 0;
  1802. X    address[i] = '\0';
  1803. X    if (i > 0)
  1804. X        strlistadd(&aka.al_addresses, address);
  1805. X    sort_list(&aka.al_addresses, pstrcmp);
  1806. X    /*
  1807. X     * Now get the group, class, and sig bindings
  1808. X     */
  1809. X    p.p_cp = fgets(line, BUFSIZ, bindf);
  1810. X    if (!p.p_cp) {
  1811. X       err1("getalent(): %s: unexpected EOF", ALBIND);
  1812. X       err1("getalent(): %s corrupted, gagging... returning 0", ALBIND);
  1813. X       return (struct alias *) 0;
  1814. X    }
  1815. X    p.p_ap = alskip(p.p_ap, ':');
  1816. X    if (!eq(line, aka.al_name)) {
  1817. X       err("getalent(): alias name mismatch");
  1818. X       err1("getalent(): %s corrupted, gagging... returning 0", ALBIND);
  1819. X       return (struct alias *) 0;
  1820. X    }
  1821. X    (void) alskip(p.p_ap, '\n');
  1822. X    oldp.p_ap = p.p_ap;
  1823. X    q = &aka.al_groups;
  1824. X    while( *p.p_cp && *p.p_cp != ':' ) {
  1825. X        oldp.p_ap = p.p_ap;
  1826. X        p.p_ap = alskip(p.p_ap,',');
  1827. X        strlistadd(q, oldp.p_cp);
  1828. X    }
  1829. X    sort_list(q, pstrcmp);
  1830. X    p.p_cp++;
  1831. X    q = &aka.al_classes;
  1832. X    while( *p.p_cp && *p.p_cp != ':' ) {
  1833. X        oldp.p_ap = p.p_ap;
  1834. X        p.p_ap = alskip(p.p_ap,',');
  1835. X        strlistadd(q, oldp.p_cp);
  1836. X    }
  1837. X    sort_list(q, pstrcmp);
  1838. X    p.p_cp++;
  1839. X    q = &aka.al_sigs;
  1840. X    while( *p.p_cp && *p.p_cp != ':' ) {
  1841. X        oldp.p_ap = p.p_ap;
  1842. X        p.p_ap = alskip(p.p_ap,',');
  1843. X        strlistadd(q, oldp.p_cp);
  1844. X    }
  1845. X    sort_list(q, pstrcmp);
  1846. X    return &aka;
  1847. X}
  1848. X
  1849. Xstruct alias *
  1850. Xgetalnam(name)
  1851. Xchar *name;
  1852. X
  1853. X{
  1854. X    int found;
  1855. X    register int indx;
  1856. X
  1857. X    indx = search_list(&AliasList, name, saliascmp, &found);
  1858. X    if (found)
  1859. X        return (struct alias *) AliasList.l_list[indx];
  1860. X    return (struct alias *) 0;
  1861. X}
  1862. X
  1863. X#endif
  1864. @//E*O*F src/alias.c//
  1865. if test 3382 -ne "`wc -c <'src/alias.c'`"; then
  1866.     echo shar: error transmitting "'src/alias.c'" '(should have been 3382 characters)'
  1867. fi
  1868. fi # end of overwriting check
  1869. echo shar: extracting "'src/backup.c'" '(2195 characters)'
  1870. if test -f 'src/backup.c' ; then 
  1871.   echo shar: will not over-write existing file "'src/backup.c'"
  1872. else
  1873. sed 's/^X//' >src/backup.c <<'@//E*O*F src/backup.c//'
  1874. X/**************************************************************************\
  1875. X*                                        *
  1876. X*     backup.c                               *
  1877. X*                                        *
  1878. X* Before the account files are modified mcp back them up.  THe files are   *
  1879. X* backed up only once per mcp session; if you save-changes more than once  *
  1880. X* the backups will still contain the files as they were when the mcp       *
  1881. X* session started, NOT the result of the last save-changes.           *
  1882. X*                                        *
  1883. X\**************************************************************************/
  1884. X
  1885. X#include <sys/file.h>
  1886. X#include <stdio.h>
  1887. X#include "sysdep.h"
  1888. X#include "mem.h"
  1889. X#include "save.h"
  1890. X
  1891. Xstatic    int BackedUp = 0;
  1892. Xextern    char *sprintf();
  1893. X
  1894. X/*
  1895. X * Will only backup one file per call!  Don't pass all of ModBits to this
  1896. X * routine at once.
  1897. X */
  1898. Xbackup(flag)
  1899. Xint flag;
  1900. X
  1901. X{
  1902. X    char *old, *new;
  1903. X
  1904. X    if (BackedUp & flag)
  1905. X        return 1;
  1906. X    switch (flag) {
  1907. X    case AC:
  1908. X        old = ACFILE;
  1909. X        new = ACBAK;
  1910. X        break;
  1911. X#ifdef SENDMAIL
  1912. X    case AL:
  1913. X        if (copyfile(ALBIND, ALBINDBAK) == 0)
  1914. X        return 0;
  1915. X        old = ALIASFILE;
  1916. X        new = ALIASBAK;
  1917. X        break;
  1918. X#endif
  1919. X    case CS:
  1920. X        old = CSFILE;
  1921. X        new = CSBAK;
  1922. X        break;
  1923. X    case GR:
  1924. X        old = GRPFILE;
  1925. X        new = GRPBAK;
  1926. X        break;
  1927. X    case PW:
  1928. X        old = PWDFILE;
  1929. X        new = PWDBAK;
  1930. X        break;
  1931. X    case RG:
  1932. X        old = RANGEFILE;
  1933. X        new = RANGEBAK;
  1934. X        break;
  1935. X    case SG:
  1936. X        old = SIGFILE;
  1937. X        new = SIGBAK;
  1938. X        break;
  1939. X    case VG:
  1940. X        old = VIGFILE;
  1941. X        new = VIGBAK;
  1942. X        break;
  1943. X    default:
  1944. X        break;
  1945. X    }
  1946. X    if (copyfile(old, new) != 0) {
  1947. X        BackedUp |= flag;
  1948. X        return 1;
  1949. X    }
  1950. X    return 0;
  1951. X}
  1952. X
  1953. Xcopyfile(from, to)
  1954. Xchar *from, *to;
  1955. X
  1956. X{
  1957. X    char buf[BUFSIZ+1];
  1958. X    int n, fromfd, tofd;
  1959. X    char errmsg[LONG_BUF];
  1960. X
  1961. X    if ((fromfd = open(from, O_RDONLY)) < 0) {
  1962. X        perr(from);
  1963. X        err2("copy %s -> %s failed", from, to);
  1964. X        return 0;
  1965. X    }
  1966. X    if ((tofd = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
  1967. X        perr(from);
  1968. X        err2("copy %s -> %s failed", from, to);
  1969. X        return 0;
  1970. X    }
  1971. X    while ((n = read(fromfd, buf, BUFSIZ)) > 0)
  1972. X        if (write(tofd, buf, n) != n) {
  1973. X        (void) sprintf(errmsg, "write of %d bytes to %s failed", n,
  1974. X                to);
  1975. X        perr(errmsg);
  1976. X        err2("copy %s -> %s failed", from, to);
  1977. X        }
  1978. X    (void) close(fromfd);
  1979. X    (void) close(tofd);
  1980. X    return 1;
  1981. X}
  1982. @//E*O*F src/backup.c//
  1983. if test 2195 -ne "`wc -c <'src/backup.c'`"; then
  1984.     echo shar: error transmitting "'src/backup.c'" '(should have been 2195 characters)'
  1985. fi
  1986. fi # end of overwriting check
  1987. echo shar: extracting "'src/class.c'" '(1809 characters)'
  1988. if test -f 'src/class.c' ; then 
  1989.   echo shar: will not over-write existing file "'src/class.c'"
  1990. else
  1991. sed 's/^X//' >src/class.c <<'@//E*O*F src/class.c//'
  1992. X#include <sys/types.h>
  1993. X#include <sys/file.h>
  1994. X#include <stdio.h>
  1995. X#include "sysdep.h"
  1996. X#include "mem.h"
  1997. X#include "lists.h"
  1998. X#include "class.h"
  1999. X
  2000. Xextern    struct list ClassList;
  2001. Xextern    int sclasscmp();
  2002. Xlong    lseek();
  2003. X
  2004. Xstatic char cdesc[DESCSIZE+1], cname[SHORT_BUF], csize[SHORT_BUF];
  2005. Xstatic char cexp[SHORT_BUF];
  2006. Xstruct class cs = { cname, 0, (time_t)0, cdesc };
  2007. X
  2008. Xint CS_FileDes = UNDEFINED;
  2009. X
  2010. Xsetcsent()
  2011. X
  2012. X{
  2013. X    if (CS_FileDes == UNDEFINED) {
  2014. X        CS_FileDes = open(CSFILE, O_RDONLY);
  2015. X        if (CS_FileDes < 0) {
  2016. X            perr(CSFILE);
  2017. X            goodbye(1);
  2018. X        }
  2019. X    }
  2020. X    lseek(CS_FileDes, (long) 0, L_SET)<0 &&
  2021. X        perr("setcsent: lseek failed?!");
  2022. X    return;
  2023. X}
  2024. X
  2025. Xendcsent()
  2026. X
  2027. X{
  2028. X    if (CS_FileDes == UNDEFINED)
  2029. X        return;
  2030. X    (void) close(CS_FileDes);
  2031. X    CS_FileDes = UNDEFINED;
  2032. X    return;
  2033. X}
  2034. X
  2035. Xstruct class *
  2036. Xgetcsent()
  2037. X
  2038. X{
  2039. X    register int i;
  2040. X    char c;
  2041. X
  2042. X    if (CS_FileDes == UNDEFINED)
  2043. X        setcsent();
  2044. X#ifdef SENDMAIL
  2045. X    zerolist(&cs.cs_aliases);
  2046. X#endif
  2047. X    i = 0;
  2048. X    while (read(CS_FileDes, &c, 1) != 0) {
  2049. X        c &= 0177;
  2050. X        if (c == ' ')
  2051. X            break;
  2052. X        cname[i++] = c;
  2053. X    }
  2054. X    if (i == 0)
  2055. X        return(0);
  2056. X    cname[i] = '\0';
  2057. X    i = 0;
  2058. X    while (read(CS_FileDes, &c, 1) != 0) {
  2059. X        c &= 0177;
  2060. X        if (c == ' ')
  2061. X            break;
  2062. X        csize[i++] = c;
  2063. X    }
  2064. X    csize[i] = '\0';
  2065. X    i = 0;
  2066. X    while (read(CS_FileDes, &c, 1) != 0) {
  2067. X        c &= 0177;
  2068. X        if (c == '\n')
  2069. X            break;
  2070. X        cexp[i++] = c;
  2071. X    }
  2072. X    if (i == 0)
  2073. X        return(0);
  2074. X    cexp[i] = '\0';
  2075. X    /* result of intermediate assignment used in read() to stifle lint */
  2076. X    cs.cs_dsize = i = atoi(csize);
  2077. X    cs.cs_exptime = atoi(cexp);
  2078. X    if (read(CS_FileDes, cs.cs_desc, i) != cs.cs_dsize)
  2079. X        fatal1("%s: bad file format", CSFILE);
  2080. X    cs.cs_desc[cs.cs_dsize] = '\0';
  2081. X    return(&cs);
  2082. X}
  2083. X
  2084. Xstruct class *
  2085. Xgetcsnam(name)
  2086. Xchar *name;
  2087. X
  2088. X{
  2089. X    int indx, found;
  2090. X
  2091. X    indx = search_list(&ClassList, name, sclasscmp, &found);
  2092. X    if (found)
  2093. X        return (struct class *) ClassList.l_list[indx];
  2094. X    return (struct class *) 0;
  2095. X}
  2096. @//E*O*F src/class.c//
  2097. if test 1809 -ne "`wc -c <'src/class.c'`"; then
  2098.     echo shar: error transmitting "'src/class.c'" '(should have been 1809 characters)'
  2099. fi
  2100. fi # end of overwriting check
  2101. echo shar: extracting "'src/class.h'" '(303 characters)'
  2102. if test -f 'src/class.h' ; then 
  2103.   echo shar: will not over-write existing file "'src/class.h'"
  2104. else
  2105. sed 's/^X//' >src/class.h <<'@//E*O*F src/class.h//'
  2106. Xstruct class {
  2107. X    char        *cs_name;
  2108. X    off_t        cs_dsize;    /* description size (bytes) */
  2109. X    time_t        cs_exptime;    /* expiration date (0=never) */
  2110. X    char        *cs_desc;    /* pointer to description */
  2111. X#ifdef SENDMAIL
  2112. X    struct list    cs_aliases;    /* aliases class is bound to */
  2113. X#endif
  2114. X};
  2115. X
  2116. Xstruct class *getcsent(), *getcsnam();
  2117. @//E*O*F src/class.h//
  2118. if test 303 -ne "`wc -c <'src/class.h'`"; then
  2119.     echo shar: error transmitting "'src/class.h'" '(should have been 303 characters)'
  2120. fi
  2121. fi # end of overwriting check
  2122. echo shar: extracting "'src/command.h'" '(167 characters)'
  2123. if test -f 'src/command.h' ; then 
  2124.   echo shar: will not over-write existing file "'src/command.h'"
  2125. else
  2126. sed 's/^X//' >src/command.h <<'@//E*O*F src/command.h//'
  2127. Xstruct command {
  2128. X    char    *c_name;    /* name of command */
  2129. X    int    (*c_func)();    /* function to call to do command */
  2130. X    short    c_su;        /* boolean; is command for root only? */
  2131. X};
  2132. @//E*O*F src/command.h//
  2133. if test 167 -ne "`wc -c <'src/command.h'`"; then
  2134.     echo shar: error transmitting "'src/command.h'" '(should have been 167 characters)'
  2135. fi
  2136. fi # end of overwriting check
  2137. echo shar: extracting "'src/gpa.h'" '(42 characters)'
  2138. if test -f 'src/gpa.h' ; then 
  2139.   echo shar: will not over-write existing file "'src/gpa.h'"
  2140. else
  2141. sed 's/^X//' >src/gpa.h <<'@//E*O*F src/gpa.h//'
  2142. X#define    G_P_A__SIZE    512
  2143. X
  2144. Xaddr *get_gpa();
  2145. @//E*O*F src/gpa.h//
  2146. if test 42 -ne "`wc -c <'src/gpa.h'`"; then
  2147.     echo shar: error transmitting "'src/gpa.h'" '(should have been 42 characters)'
  2148. fi
  2149. fi # end of overwriting check
  2150. echo shar: "End of archive 3 (of 8)."
  2151. cp /dev/null ark3isdone
  2152. DONE=true
  2153. for I in 1 2 3 4 5 6 7 8; do
  2154.     if test -! f ark${I}isdone; then
  2155.         echo "You still need to run archive ${I}."
  2156.         DONE=false
  2157.     fi
  2158. done
  2159. case $DONE in
  2160.     true)
  2161.         echo "You have run all 8 archives."
  2162.         echo 'See the README file'
  2163.         ;;
  2164. esac
  2165. ##  End of shell archive.
  2166. exit 0
  2167.