home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / mcp / part04 < prev    next >
Encoding:
Internet Message Format  |  1987-02-05  |  49.8 KB

  1. Subject:  v08i044:  Account creation/manipulation program, Part04/08
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Kyle Jones <xanth!kyle>
  6. Mod.sources: Volume 8, Issue 44
  7. Archive-name: mcp/Part04
  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 4 (of 8)."
  13. # Contents:  src/bind.c src/build.c src/ckp.c src/date.c src/disable.c
  14. #   src/edit.c src/errmsg.c src/exists.c src/exit.c src/exits.c
  15. #   src/freeze.c src/groupmap.c src/groupmap.h src/history.h src/job.h
  16. # Wrapped by rs@mirror on Fri Feb  6 15:55:57 1987
  17. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  18. echo shar: extracting "'src/bind.c'" '(12012 characters)'
  19. if test -f 'src/bind.c' ; then 
  20.   echo shar: will not over-write existing file "'src/bind.c'"
  21. else
  22. sed 's/^X//' >src/bind.c <<'@//E*O*F src/bind.c//'
  23. X/***************************************************************************\
  24. X*                                         *
  25. X*     bind.c                                    *
  26. X*                                         *
  27. X* Herein lie most of the user interface routines to bind classes, sigs and  *
  28. X* groups to sendmail aliases.  The idea behind the bindings is that        *
  29. X* accurate e-mail mailing lists can be maintained most easily be        *
  30. X* integrating their maintenance into the same software that creates and        *
  31. X* deletes accounts.                                *
  32. X*                                         *
  33. X\***************************************************************************/
  34. X
  35. X#include <stdio.h>
  36. X#include <sys/types.h>
  37. X#include <lastlog.h>
  38. X#include "sysdep.h"
  39. X
  40. X#ifdef SENDMAIL
  41. X#include "macros.h"
  42. X#include "mem.h"
  43. X#include "gpa.h"
  44. X#include "lists.h"
  45. X#include "account.h"
  46. X#include "alias.h"
  47. X#include "class.h"
  48. X#include "groupmap.h"
  49. X#include "sig.h"
  50. X#include "sort.h"
  51. X#include "save.h"
  52. X
  53. Xextern    struct list AccountList, Aliases, AliasList;
  54. Xextern    int ModBits;
  55. X
  56. Xbindgroup(c, v)
  57. Xint c;
  58. Xaddr *v;
  59. X
  60. X{
  61. X    struct alias *al;
  62. X    struct account *ac;
  63. X    struct groupmap *gm;
  64. X    addr *aliasv;
  65. X    int cc, bound = 0;
  66. X    register int i, j;
  67. X
  68. X    if (c > 2) {
  69. X        err1("%s: too many arguments", (char *)v[0]);
  70. X        return;
  71. X    }
  72. X    if (c != 2) {
  73. X        err1("usage: %s <group>", (char *)v[0]);
  74. X        return;
  75. X    }
  76. X    gm = getgmnam((char *)v[1]);
  77. X    if (!gm) {
  78. X        err1("%s: no such group", (char *)v[1]);
  79. X        return;
  80. X    }
  81. X
  82. X    aliasv = get_gpa(17);
  83. X    GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases);
  84. X    if (cc == 0) {
  85. X        err("no change");
  86. X        return;
  87. X    }
  88. X
  89. X    for (i=0; i < cc; i++) {
  90. X        al = getalnam((char *)aliasv[i]);
  91. X        if (!al) {
  92. X        err1("%s: no such alias", (char *)aliasv[i]);
  93. X        continue;
  94. X        }
  95. X        if (instrlist(&al->al_groups, (char *)v[1])) {
  96. X        err2("%s: already bound to %s", (char *)v[1], al->al_name);
  97. X        continue;
  98. X        }
  99. X        strlistadd(&al->al_groups, (char *)v[1]);
  100. X        strlistadd(&gm->gm_aliases, al->al_name);
  101. X        sort_list(&al->al_groups, pstrcmp);
  102. X        sort_list(&gm->gm_aliases, pstrcmp);
  103. X        for (j=0; j < AccountList.l_count; j++) {
  104. X        ac = (struct account *) AccountList.l_list[j];
  105. X        if (ac->ac_gid != gm->gm_gid &&
  106. X            !instrlist(&ac->ac_groups, (char *)v[1]))
  107. X            continue;
  108. X        if (instrlist(&al->al_addresses, (char *)ac->ac_name))
  109. X            continue;
  110. X        strlistadd(&al->al_addresses, (char *)ac->ac_name);
  111. X        sort_list(&al->al_addresses, pstrcmp);
  112. X        }
  113. X        bound++;
  114. X    }
  115. X    if (bound) {
  116. X        ModBits |= AL;
  117. X        (void) printf("%d bound\n", bound);
  118. X    }
  119. X    non_critical();
  120. X
  121. X    return;
  122. X}
  123. X
  124. Xbindclass(c, v)
  125. Xint c;
  126. Xaddr *v;
  127. X
  128. X{
  129. X    struct alias *al;
  130. X    struct account *ac;
  131. X    struct class *cs;
  132. X    addr *aliasv;
  133. X    int cc, bound = 0;
  134. X    register int i, j;
  135. X
  136. X    if (c > 2) {
  137. X        err1("%s: too many arguments", (char *)v[0]);
  138. X        return;
  139. X    }
  140. X    if (c != 2) {
  141. X        err1("usage: %s <class>", (char *)v[0]);
  142. X        return;
  143. X    }
  144. X    cs = getcsnam((char *)v[1]);
  145. X    if (!cs) {
  146. X        err1("%s: no such class", (char *)v[1]);
  147. X        return;
  148. X    }
  149. X
  150. X    aliasv = get_gpa(17);
  151. X    GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases);
  152. X    if (cc == 0) {
  153. X        err("no change");
  154. X        return;
  155. X    }
  156. X
  157. X    for (i=0; i < cc; i++) {
  158. X        al = getalnam((char *)aliasv[i]);
  159. X        if (!al) {
  160. X        err1("%s: no such alias", (char *)aliasv[i]);
  161. X        continue;
  162. X        }
  163. X        if (instrlist(&al->al_classes, (char *)v[1])) {
  164. X        err2("%s: already bound to %s", (char *)v[1], al->al_name);
  165. X        continue;
  166. X        }
  167. X        strlistadd(&al->al_classes, (char *)v[1]);
  168. X        strlistadd(&cs->cs_aliases, al->al_name);
  169. X        sort_list(&al->al_classes, pstrcmp);
  170. X        sort_list(&cs->cs_aliases, pstrcmp);
  171. X        for (j=0; j < AccountList.l_count; j++) {
  172. X        ac = (struct account *) AccountList.l_list[j];
  173. X        if (!instrlist(&ac->ac_classes, (char *)v[1]))
  174. X            continue;
  175. X        if (instrlist(&al->al_addresses, (char *)ac->ac_name))
  176. X            continue;
  177. X        strlistadd(&al->al_addresses, (char *)ac->ac_name);
  178. X        sort_list(&al->al_addresses, pstrcmp);
  179. X        }
  180. X        bound++;
  181. X    }
  182. X    if (bound) {
  183. X        ModBits |= AL;
  184. X        (void) printf("%d bound\n", bound);
  185. X    }
  186. X    non_critical();
  187. X
  188. X    return;
  189. X}
  190. X
  191. Xbindsig(c, v)
  192. Xint c;
  193. Xaddr *v;
  194. X
  195. X{
  196. X    struct alias *al;
  197. X    struct account *ac;
  198. X    struct sig *sg;
  199. X    addr *aliasv;
  200. X    int cc, bound = 0;
  201. X    register int i, j;
  202. X
  203. X    if (c > 2) {
  204. X        err1("%s: too many arguments", (char *)v[0]);
  205. X        return;
  206. X    }
  207. X    if (c != 2) {
  208. X        err1("usage: %s <sig>", (char *)v[0]);
  209. X        return;
  210. X    }
  211. X    sg = getsgnam((char *)v[1]);
  212. X    if (!sg) {
  213. X        err1("%s: no such sig", (char *)v[1]);
  214. X        return;
  215. X    }
  216. X
  217. X    aliasv = get_gpa(17);
  218. X    GetLine("To-Aliases: ", 16, &cc, aliasv, &Aliases);
  219. X    if (cc == 0) {
  220. X        err("no change");
  221. X        return;
  222. X    }
  223. X
  224. X    for (i=0; i < cc; i++) {
  225. X        al = getalnam((char *)aliasv[i]);
  226. X        if (!al) {
  227. X        err1("%s: no such alias", (char *)aliasv[i]);
  228. X        continue;
  229. X        }
  230. X        if (instrlist(&al->al_sigs, (char *)v[1])) {
  231. X        err2("%s: already bound to %s", (char *)v[1], al->al_name);
  232. X        continue;
  233. X        }
  234. X        strlistadd(&al->al_sigs, (char *)v[1]);
  235. X        strlistadd(&sg->sg_aliases, al->al_name);
  236. X        sort_list(&al->al_sigs, pstrcmp);
  237. X        sort_list(&sg->sg_aliases, pstrcmp);
  238. X        for (j=0; j < AccountList.l_count; j++) {
  239. X        ac = (struct account *) AccountList.l_list[j];
  240. X        if (!instrlist(&ac->ac_sigs, (char *)v[1]))
  241. X            continue;
  242. X        if (instrlist(&al->al_addresses, (char *)ac->ac_name))
  243. X            continue;
  244. X        strlistadd(&al->al_addresses, (char *)ac->ac_name);
  245. X        sort_list(&al->al_addresses, pstrcmp);
  246. X        }
  247. X        bound++;
  248. X    }
  249. X    if (bound) {
  250. X        ModBits |= AL;
  251. X        (void) printf("%d bound\n", bound);
  252. X    }
  253. X    non_critical();
  254. X
  255. X    return;
  256. X}
  257. X
  258. Xubindgroup(c, v)
  259. Xint c;
  260. Xaddr *v;
  261. X
  262. X{
  263. X    struct account *ac;
  264. X    struct alias *al;
  265. X    struct groupmap *gm;
  266. X    addr *aliasv;
  267. X    register int i, j;
  268. X    int unbound = 0, cc;
  269. X
  270. X    if (c > 2) {
  271. X        err1("%s: too many arguements", (char *)v[0]);
  272. X        return;
  273. X    }
  274. X    if (c < 2) {
  275. X        err1("usage: %s <group>", (char *)v[0]);
  276. X        return;
  277. X    }
  278. X    gm = getgmnam((char *)v[1]);
  279. X    if (!gm) {
  280. X        err1("%s: no such group", (char *)v[1]);
  281. X        return;
  282. X    }
  283. X    if (gm->gm_aliases.l_count) {
  284. X        err1("%s: not bound to any aliases", gm->gm_name);
  285. X        return;
  286. X    }
  287. X
  288. X    aliasv = get_gpa(17);
  289. X    GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases);
  290. X    if (cc == 0) {
  291. X        err("no change");
  292. X        return;
  293. X    }
  294. X
  295. X    critical();
  296. X    for (i=0; i < cc; i++) {
  297. X        al = getalnam((char *)aliasv[i]);
  298. X        if (!al) {
  299. X        err1("%s: no such alias", (char *)aliasv[i]);
  300. X        continue;
  301. X        }
  302. X        if (!instrlist(&al->al_groups, (char *)v[1])) {
  303. X        err2("%s: not bound to %s", (char *)v[1], al->al_name);
  304. X        continue;
  305. X        }
  306. X        strlistdel(&al->al_groups, (char *)v[1]);
  307. X        strlistdel(&gm->gm_aliases, al->al_name);
  308. X        for (j=0; j < AccountList.l_count; j++) {
  309. X        ac = (struct account *) AccountList.l_list[j];
  310. X        if (!instrlist(&al->al_addresses, (char *)ac->ac_name))
  311. X            continue;
  312. X        if (LegalAKA(ac, al))
  313. X            continue;
  314. X        strlistdel(&al->al_addresses, (char *)ac->ac_name);
  315. X        }
  316. X        unbound++;
  317. X    }
  318. X    if (unbound) {
  319. X        (void) printf("%d unbound\n", unbound);
  320. X        ModBits |= AL;
  321. X    }
  322. X    non_critical();
  323. X
  324. X    return;
  325. X}
  326. X
  327. Xubindclass(c, v)
  328. Xint c;
  329. Xaddr *v;
  330. X
  331. X{
  332. X    struct account *ac;
  333. X    struct alias *al;
  334. X    struct class *cs;
  335. X    addr *aliasv;
  336. X    register int i, j;
  337. X    int unbound = 0, cc;
  338. X
  339. X    if (c > 2) {
  340. X        err1("%s: too many arguements", (char *)v[0]);
  341. X        return;
  342. X    }
  343. X    if (c < 2) {
  344. X        err1("usage: %s <class>", (char *)v[0]);
  345. X        return;
  346. X    }
  347. X    cs = getcsnam((char *)v[1]);
  348. X    if (!cs) {
  349. X        err1("%s: no such class", (char *)v[1]);
  350. X        return;
  351. X    }
  352. X    if (cs->cs_aliases.l_count) {
  353. X        err1("%s: not bound to any aliases", cs->cs_name);
  354. X        return;
  355. X    }
  356. X
  357. X    aliasv = get_gpa(17);
  358. X    GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases);
  359. X    if (cc == 0) {
  360. X        err("no change");
  361. X        return;
  362. X    }
  363. X
  364. X    critical();
  365. X    for (i=0; i < cc; i++) {
  366. X        al = getalnam((char *)aliasv[i]);
  367. X        if (!al) {
  368. X        err1("%s: no such alias", (char *)aliasv[i]);
  369. X        continue;
  370. X        }
  371. X        if (!instrlist(&al->al_classes, (char *)v[1])) {
  372. X        err2("%s: not bound to %s", (char *)v[1], al->al_name);
  373. X        continue;
  374. X        }
  375. X        strlistdel(&al->al_classes, (char *)v[1]);
  376. X        strlistdel(&cs->cs_aliases, al->al_name);
  377. X        for (j=0; j < AccountList.l_count; j++) {
  378. X        ac = (struct account *) AccountList.l_list[j];
  379. X        if (!instrlist(&ac->ac_classes, (char *)v[1]))
  380. X            continue;
  381. X        if (!instrlist(&al->al_addresses, (char *)ac->ac_name))
  382. X            continue;
  383. X        if (LegalAKA(ac, al))
  384. X            continue;
  385. X        strlistdel(&al->al_addresses, (char *)ac->ac_name);
  386. X        }
  387. X        unbound++;
  388. X    }
  389. X    if (unbound) {
  390. X        (void) printf("%d unbound\n", unbound);
  391. X        ModBits |= AL;
  392. X    }
  393. X    non_critical();
  394. X
  395. X    return;
  396. X}
  397. X
  398. Xubindsig(c, v)
  399. Xint c;
  400. Xaddr *v;
  401. X
  402. X{
  403. X    struct account *ac;
  404. X    struct alias *al;
  405. X    struct sig *sg;
  406. X    addr *aliasv;
  407. X    register int i, j;
  408. X    int unbound = 0, cc;
  409. X
  410. X    if (c > 2) {
  411. X        err1("%s: too many arguements", (char *)v[0]);
  412. X        return;
  413. X    }
  414. X    if (c < 2) {
  415. X        err1("usage: %s <sig>", (char *)v[0]);
  416. X        return;
  417. X    }
  418. X    sg = getsgnam((char *)v[1]);
  419. X    if (!sg) {
  420. X        err1("%s: no such sig", (char *)v[1]);
  421. X        return;
  422. X    }
  423. X    if (sg->sg_aliases.l_count) {
  424. X        err1("%s: not bound to any aliases", sg->sg_name);
  425. X        return;
  426. X    }
  427. X
  428. X    aliasv = get_gpa(17);
  429. X    GetLine("From-Aliases: ", 16, &cc, aliasv, &Aliases);
  430. X    if (cc == 0) {
  431. X        err("no change");
  432. X        return;
  433. X    }
  434. X
  435. X    critical();
  436. X    for (i=0; i < cc; i++) {
  437. X        al = getalnam((char *)aliasv[i]);
  438. X        if (!al) {
  439. X        err1("%s: no such alias", (char *)aliasv[i]);
  440. X        continue;
  441. X        }
  442. X        if (!instrlist(&al->al_sigs, (char *)v[1])) {
  443. X        err2("%s: not bound to %s", (char *)v[1], al->al_name);
  444. X        continue;
  445. X        }
  446. X        strlistdel(&al->al_sigs, (char *)v[1]);
  447. X        strlistdel(&sg->sg_aliases, al->al_name);
  448. X        for (j=0; j < AccountList.l_count; j++) {
  449. X        ac = (struct account *) AccountList.l_list[j];
  450. X        if (!instrlist(&ac->ac_sigs, (char *)v[1]))
  451. X            continue;
  452. X        if (!instrlist(&al->al_addresses, (char *)ac->ac_name))
  453. X            continue;
  454. X        if (LegalAKA(ac, al))
  455. X            continue;
  456. X        strlistdel(&al->al_addresses, (char *)ac->ac_name);
  457. X        }
  458. X        unbound++;
  459. X    }
  460. X    if (unbound) {
  461. X        (void) printf("%d unbound\n", unbound);
  462. X        ModBits |= AL;
  463. X    }
  464. X    non_critical();
  465. X
  466. X    return;
  467. X}
  468. X
  469. X/*
  470. X * Routine to determine if a user should be left in an alias after
  471. X * his class, sig, or group memberships have changed.  If the user is still
  472. X * a member of another class, sig or group that is bound to the given aliasm
  473. X * then the user should remain in the alias.  Also if the user a member of
  474. X * the alias above and beyond any class, sig or group bindings he should be
  475. X * allowed to remain.
  476. X */
  477. Xint
  478. XLegalAKA(ac, al)
  479. Xstruct account *ac;
  480. Xstruct alias *al;
  481. X
  482. X{
  483. X    char *name;
  484. X    struct groupmap *gm;
  485. X    register int i;
  486. X
  487. X    /*
  488. X     * REMEMBER:
  489. X     * ac_aliases always contains the list of aliasses that the user is
  490. X     * in, even if he were not member of classes, sig, etc. that
  491. X     * are bound to aliases.  Thus class, sig, or group membership
  492. X     * changes have no bearing on this so we return 1 immediately.
  493. X     */
  494. X    if (instrlist(&ac->ac_aliases, al->al_name))
  495. X        return 1;
  496. X    /*
  497. X     * Check for membership via group being bound.
  498. X     */
  499. X    gm = getgmgid(ac->ac_gid);
  500. X    if (gm && instrlist(&al->al_groups, (char *)gm->gm_name))
  501. X        return 1;
  502. X    for (i=0; i < ac->ac_groups.l_count; i++) {
  503. X        name = (char *) ac->ac_groups.l_list[i];
  504. X        if (instrlist(&al->al_groups, name))
  505. X        return 1;
  506. X    }
  507. X    /*
  508. X     * Are any of this user's classes bound to this alias?
  509. X     */
  510. X    for (i=0; i < ac->ac_classes.l_count; i++) {
  511. X        name = (char *) ac->ac_classes.l_list[i];
  512. X        if (instrlist(&al->al_classes, name))
  513. X        return 1;
  514. X    }
  515. X    /*
  516. X     * Are any of this user's sigs bound to this alias?
  517. X     */
  518. X    for (i=0; i < ac->ac_sigs.l_count; i++) {
  519. X        name = (char *) ac->ac_sigs.l_list[i];
  520. X        if (instrlist(&al->al_sigs, name))
  521. X        return 1;
  522. X    }
  523. X    return 0;
  524. X}
  525. X
  526. X/*
  527. X * Patch up aliases.
  528. X * Should be used right after removing users from classes,
  529. X * sigs, or groups, to be sure that if these are bound the changes are
  530. X * reflected in the aliases.
  531. X */
  532. XRXBindings(ac)
  533. Xstruct account *ac;
  534. X
  535. X{
  536. X    register struct alias *al;
  537. X    register int i;
  538. X
  539. X    critical();
  540. X    for (i=0; i < AliasList.l_count; i++) {
  541. X    al = (struct alias *) AliasList.l_list[i];
  542. X    if (instrlist(&al->al_addresses, (char *)ac->ac_name)) {
  543. X        if (LegalAKA(ac, al) == 0) {
  544. X        strlistdel(&al->al_addresses, (char *)ac->ac_name);
  545. X        ModBits |= AL;
  546. X        }
  547. X    }
  548. X    }
  549. X    non_critical();
  550. X    return;
  551. X}
  552. X
  553. X#endif SENDMAIL
  554. @//E*O*F src/bind.c//
  555. if test 12012 -ne "`wc -c <'src/bind.c'`"; then
  556.     echo shar: error transmitting "'src/bind.c'" '(should have been 12012 characters)'
  557. fi
  558. fi # end of overwriting check
  559. echo shar: extracting "'src/build.c'" '(5892 characters)'
  560. if test -f 'src/build.c' ; then 
  561.   echo shar: will not over-write existing file "'src/build.c'"
  562. else
  563. sed 's/^X//' >src/build.c <<'@//E*O*F src/build.c//'
  564. X/***************************************************************************\
  565. X*                                         *
  566. X*     build.c                                    *
  567. X*                                         *
  568. X* Routines to build the accounts file from the existing passwd and group    *
  569. X* files, i.e. the -I option to mcp.  All information about who is in what   *
  570. X* class and what sig is destroyed by this process.  If the class, sig, vig  *
  571. X* or range files do not exist, mcp will attempt to create them, otherwise   *
  572. X* these are untouched.                                *
  573. X*                                         *
  574. X\***************************************************************************/
  575. X
  576. X#include <stdio.h>
  577. X#include <sys/file.h>
  578. X#include <sys/types.h>
  579. X#include <strings.h>
  580. X#include <pwd.h>
  581. X#include <grp.h>
  582. X#include <lastlog.h>
  583. X#include "sysdep.h"
  584. X#include "macros.h"
  585. X#include "mem.h"
  586. X#include "lists.h"
  587. X#ifdef SENDMAIL
  588. X#include "alias.h"
  589. X#endif
  590. X#include "account.h"
  591. X#include "groupmap.h"
  592. X#include "sort.h"
  593. X#include "save.h"
  594. X#ifdef SENDMAIL
  595. X#include <ctype.h>
  596. X#endif
  597. X
  598. Xextern    struct list AccountList, GroupMapList, Groups, Users;
  599. Xextern    int ModBits, root, acck();
  600. X
  601. XBuild()
  602. X
  603. X{
  604. X#ifdef SENDMAIL
  605. X    struct alias *al;
  606. X    char line[BUFSIZ];
  607. X#endif
  608. X    struct account a, *ac, *ac2;
  609. X    struct passwd *pw;
  610. X    struct group *gr;
  611. X    struct groupmap gm;
  612. X    register int indx;
  613. X    char *cp;
  614. X
  615. X    ShowVersion();
  616. X    msg("Building accounting files...");
  617. X#ifdef SENDMAIL
  618. X    zerolist(&a.ac_aliases);
  619. X#endif
  620. X    zerolist(&a.ac_groups);
  621. X    zerolist(&a.ac_classes);   zerolist(&a.ac_sigs);
  622. X    (void) setpwent();
  623. X    while (pw = getpwent()) {
  624. X        a.ac_uid = pw->pw_uid;
  625. X        a.ac_gid = pw->pw_gid;
  626. X        savestr((char **)&a.ac_name, pw->pw_name);
  627. X        savestr((char **)&a.ac_gecos, pw->pw_gecos);
  628. X        cp = index(pw->pw_gecos, ',');    if (cp) *cp = '\0';
  629. X        savestr((char **)&a.ac_realname, pw->pw_gecos);
  630. X        savestr((char **)&a.ac_passwd, pw->pw_passwd);
  631. X        savestr((char **)&a.ac_dir, pw->pw_dir);
  632. X        savestr((char **)&a.ac_shell, pw->pw_shell);
  633. X        savestr((char **)&a.ac_id, "exception");
  634. X        genlistadd(&AccountList, (addr)&a, sizeof (struct account));
  635. X        strlistadd(&Users, pw->pw_name);
  636. X    }
  637. X    sort_list(&AccountList, acctcmp);
  638. X    sort_list(&Users, pstrcmp);
  639. X    (void) endpwent();
  640. X    (void) setgrent();
  641. X    while (gr = getgrent()) {
  642. X        zerolist(&gm.gm_mem);
  643. X        gm.gm_gid = gr->gr_gid;
  644. X        savestr(&gm.gm_name, gr->gr_name);
  645. X        savestr(&gm.gm_passwd, gr->gr_passwd);
  646. X        for (indx=0; gr->gr_mem[indx]; indx++) {
  647. X            ac = getacnam(gr->gr_mem[indx]);
  648. X            if (ac) {
  649. X                strlistadd(&ac->ac_groups, gr->gr_name);
  650. X                sort_list(&ac->ac_groups, pstrcmp);
  651. X            }
  652. X            else
  653. X                continue;
  654. X            strlistadd(&gm.gm_mem, gr->gr_mem[indx]);
  655. X        }
  656. X        sort_list(&gm.gm_mem, pstrcmp);
  657. X        genlistadd(&GroupMapList, (addr)&gm, sizeof(struct groupmap));
  658. X        strlistadd(&Groups, gr->gr_name);
  659. X    }
  660. X    (void) endgrent();
  661. X    /*
  662. X     * If an accounts file already exists get the unchanged
  663. X     * information from it before overwriting it.
  664. X     */
  665. X    if (!fileexists(ACFILE)) goto finish;
  666. X    if (acck() == 0) {
  667. X        err("I can't get the class and sig membership info");
  668. X        err("nor the ID's or real names of current users");
  669. X        err("nor the non-binding alias memberships");
  670. X        err1("from the old %s because the file format is bad.",
  671. X            ACFILE);
  672. X        err("");
  673. X        if (yesno("Overwrite it anyway? ") == 0)
  674. X            fatal("aborted");
  675. X    }
  676. X    (void) setacent();
  677. X    while (ac2 = getacent()) {
  678. X        ac = getacnam((char *)ac2->ac_name);
  679. X        if (!ac) {
  680. X(void) printf("accounts line for nonexistent user \"%s\" removed\n",
  681. X            ac2->ac_name);
  682. X            continue;
  683. X        }
  684. X        FREEMEM((char *)ac->ac_realname);
  685. X        savestr((char **)&ac->ac_realname, (char *)ac2->ac_realname);
  686. X        FREEMEM((char *)ac->ac_id);
  687. X        savestr((char **)&ac->ac_id, (char *)ac2->ac_id);
  688. X        duplist(&ac->ac_classes, &ac2->ac_classes);
  689. X        duplist(&ac->ac_sigs, &ac2->ac_sigs);
  690. X#ifdef SENDMAIL
  691. X        duplist(&ac->ac_aliases, &ac2->ac_aliases);
  692. X#endif
  693. X    }
  694. Xfinish:
  695. X    !fileexists(CSFILE) && createfile(CSFILE);
  696. X    !fileexists(RANGEFILE) && createfile(RANGEFILE);
  697. X    !fileexists(SIGFILE) && createfile(SIGFILE);
  698. X    !fileexists(VIGFILE) && createfile(VIGFILE);
  699. X    !fileexists(SHELLFILE) && createfile(SHELLFILE);
  700. X    !fileexists(ACFILE) && createfile(ACFILE);
  701. X#ifdef SENDMAIL
  702. X    !fileexists(ALIASFILE) && createfile(ALIASFILE);
  703. X#endif
  704. X
  705. X    critical();
  706. X#ifdef SENDMAIL
  707. X    /*
  708. X     * Check to see if an alias bindings file needs to be created
  709. X     * to represent the current aliases file.  Also if no alias bindings
  710. X     * file exists we must assume that all users that are currently in
  711. X     * aliases are not there because of bindings, hence updating
  712. X     * ac_aliases for each user where appropriate.
  713. X     */
  714. X    if (!fileexists(ALBIND)) {
  715. X        FILE *bindf = fopen(ALBIND, "w");
  716. X        FILE *alf = fopen(ALIASFILE, "r");
  717. X
  718. X        if (alf == NULL) {
  719. X            err1("can't open %s (read)", ALIASFILE);
  720. X            fatal("mcp: -B aborted");
  721. X        }
  722. X        if (bindf == NULL) {
  723. X            (void) fclose(alf);
  724. X            err1("can't open %s (write)", ALBIND);
  725. X            fatal("mcp: -B aborted");
  726. X        }
  727. X        while (fgets(line, BUFSIZ, alf) != NULL) {
  728. X            if (isspace(line[0]) || line[0] == '#')
  729. X                continue;
  730. X            cp = index(line, '#');
  731. X            if (cp) *cp = '\0';
  732. X            cp = index(line, ':');
  733. X            if (cp) *cp = '\0';
  734. X            if (line[0] == '\n')
  735. X                continue;
  736. X            cp = index(line, '\n');
  737. X            if (cp) *cp = '\0';
  738. X            (void) fprintf(bindf, "%s:::\n", line);
  739. X        }
  740. X        (void) fchmod(fileno(bindf), 0644);
  741. X        (void) fclose(bindf);
  742. X        (void) fclose(alf);
  743. X        setalent();
  744. X        while (al = getalent()) {
  745. X            for (indx=0; indx < al->al_addresses.l_count; indx++) {
  746. X            cp = (char *) al->al_addresses.l_list[indx];
  747. X            ac = getacnam(cp);
  748. X            if (ac && !instrlist(&ac->ac_aliases, cp)) {
  749. X                strlistadd(&ac->ac_aliases, al->al_name);
  750. X                sort_list(&ac->ac_aliases, pstrcmp);
  751. X            }
  752. X            }
  753. X        }
  754. X        endalent();
  755. X    }
  756. X#endif
  757. X    if (backup(PW) == 0 || backup(AC) == 0)
  758. X        fatal("mcp: -B aborted");
  759. X    msg("");
  760. X    save_pw();
  761. X    save_ac();
  762. X    non_critical();
  763. X
  764. X    goodbye(0);
  765. X}
  766. X
  767. Xstatic
  768. Xcreatefile(file)
  769. Xchar *file;
  770. X
  771. X{
  772. X    int d;
  773. X
  774. X    d = open(file, O_WRONLY|O_CREAT);
  775. X    if (d == -1) {
  776. X        perr(file);
  777. X        return;
  778. X    }
  779. X    (void) write(d, "Toto IV", 7);
  780. X    (void) ftruncate(d, (off_t)0);
  781. X    (void) fchmod(d, 0644);
  782. X    (void) fsync(d);
  783. X    (void) close(d);
  784. X}
  785. @//E*O*F src/build.c//
  786. if test 5892 -ne "`wc -c <'src/build.c'`"; then
  787.     echo shar: error transmitting "'src/build.c'" '(should have been 5892 characters)'
  788. fi
  789. fi # end of overwriting check
  790. echo shar: extracting "'src/ckp.c'" '(6255 characters)'
  791. if test -f 'src/ckp.c' ; then 
  792.   echo shar: will not over-write existing file "'src/ckp.c'"
  793. else
  794. sed 's/^X//' >src/ckp.c <<'@//E*O*F src/ckp.c//'
  795. X/****************************************************************************\
  796. X*                                          *
  797. X*     ckp.c                                     *
  798. X*                                          *
  799. X* These are the routines that put changes that have not been saved, into     *
  800. X* the .mcp checkpoint files.  An important thing to remember here is that    *
  801. X* checkpointing should not be interupted by anything, particularly not by    *
  802. X* another checkpoint, or chaos will ensue.  There are only one set ot temp   *
  803. X* files shared by save and the checkpoint routines.  This was done for the   *
  804. X* sake of simplicity and also since the tempfiles are in the same         *
  805. X* filesystem as their accounting counterparts, these can be rename()'d into  *
  806. X* place without the possibility of being caught by a system crash with a     *
  807. X* file copy partially completed.                         *
  808. X*                                          *
  809. X\****************************************************************************/
  810. X
  811. X#include <stdio.h>
  812. X#include <sys/types.h>
  813. X#include <signal.h>
  814. X#include <lastlog.h>
  815. X#include "sysdep.h"
  816. X#include "macros.h"
  817. X#include "mem.h"
  818. X#include "lists.h"
  819. X#ifdef SENDMAIL
  820. X#include "alias.h"
  821. X#endif
  822. X#include "account.h"
  823. X#include "class.h"
  824. X#include "sig.h"
  825. X#include "range.h"
  826. X#include "groupmap.h"
  827. X#include "save.h"
  828. X
  829. Xextern    int ModBits;
  830. X
  831. X#ifdef SENDMAIL
  832. Xextern    struct list AliasList;
  833. X#endif
  834. Xextern    struct list AccountList, GroupMapList, SigList, ClassList, RangeList;
  835. Xextern    struct list Vigs, Jobs;
  836. X
  837. Xckp_pw()
  838. X
  839. X{
  840. X    FILE *pwf;
  841. X    register int i;
  842. X    struct account *ac;
  843. X
  844. X    pwf = fopen(PWDTMP, "w");
  845. X    if (pwf == NULL) {
  846. X        perr(PWDTMP);
  847. X        return;
  848. X    }
  849. X    for (i=0; i < AccountList.l_count; i++) {
  850. X        ac = (struct account *) AccountList.l_list[i];
  851. X        (void) fprintf(pwf, "%s:%s:%d:%d:%s:%s:%s\n",
  852. X            ac->ac_name,
  853. X            ac->ac_passwd,
  854. X            ac->ac_uid,
  855. X            ac->ac_gid,
  856. X            ac->ac_gecos,
  857. X            ac->ac_dir,
  858. X            ac->ac_shell);
  859. X    }
  860. X    (void) fclose(pwf);
  861. X    if (rename(PWDTMP, PWDCKP) == -1) {
  862. X        perr(PWDTMP);
  863. X        return;
  864. X    }
  865. X    return;
  866. X}
  867. X
  868. X#ifdef SENDMAIL
  869. Xckp_al()
  870. X
  871. X{
  872. X    FILE *alf, *bindf;
  873. X    struct alias *al;
  874. X    register int i;
  875. X
  876. X    alf = fopen(ALIASTMP, "w");
  877. X    if (alf == NULL) {
  878. X        perr(ALIASTMP);
  879. X        return;
  880. X    }
  881. X    bindf = fopen(ALBINDTMP, "w");
  882. X    if (bindf == NULL) {
  883. X        perr(ALBINDTMP);
  884. X        (void) fclose(alf);
  885. X        return;
  886. X    }
  887. X    for (i=0; i < AliasList.l_count; i++) {
  888. X        al = (struct alias *) AliasList.l_list[i];
  889. X        (void) fprintf(alf, "%s:", al->al_name);
  890. X        listout(&al->al_addresses, alf);
  891. X        fputs("\n", alf);
  892. X        (void) fprintf(bindf, "%s:", al->al_name);
  893. X        listout(&al->al_groups, bindf);
  894. X        fputs(":", bindf);
  895. X        listout(&al->al_classes, bindf);
  896. X        fputs(":", bindf);
  897. X        listout(&al->al_sigs, bindf);
  898. X        fputs("\n", bindf);
  899. X    }
  900. X    (void) fclose(alf);
  901. X    (void) fclose(bindf);
  902. X    if (rename(ALIASTMP, ALIASCKP) == -1) {
  903. X        perr(ALIASTMP);
  904. X        return;
  905. X    }
  906. X    if (rename(ALBINDTMP, ALBINDCKP) == -1) {
  907. X        perr(ALBINDTMP);
  908. X        return;
  909. X    }
  910. X    return;
  911. X}
  912. X#endif
  913. X
  914. Xckp_ac()
  915. X
  916. X{
  917. X    FILE *acf;
  918. X    register int i;
  919. X    struct account *ac;
  920. X
  921. X    acf = fopen(ACTMP, "w");
  922. X    if (acf == NULL) {
  923. X        perr(ACTMP);
  924. X        return;
  925. X    }
  926. X    for (i=0; i < AccountList.l_count; i++) {
  927. X        ac = (struct account *) AccountList.l_list[i];
  928. X        (void) fprintf(acf, "%s:%s:%s:%d:%d:",
  929. X            ac->ac_name,
  930. X            ac->ac_realname,
  931. X            ac->ac_id,
  932. X            ac->ac_uid,
  933. X            ac->ac_gid);
  934. X        listout(&ac->ac_groups, acf);
  935. X        fputs(":", acf);
  936. X        listout(&ac->ac_classes, acf);
  937. X        fputs(":", acf);
  938. X        listout(&ac->ac_sigs, acf);
  939. X        fputs(":", acf);
  940. X#ifdef SENDMAIL
  941. X        listout(&ac->ac_aliases, acf);
  942. X#endif
  943. X        fputs("\n", acf);
  944. X    }
  945. X    (void) fclose(acf);
  946. X    if (rename(ACTMP, ACCKP) == -1) {
  947. X        perr(ACTMP);
  948. X        return;
  949. X    }
  950. X    return;
  951. X}
  952. X
  953. Xckp_gr()
  954. X
  955. X{
  956. X    FILE *grf;
  957. X    register int i;
  958. X    struct groupmap *gm;
  959. X
  960. X    grf = fopen(GRPTMP, "w");
  961. X    if (grf == NULL) {
  962. X        perr(GRPTMP);
  963. X        return;
  964. X    }
  965. X    for (i=0; i < GroupMapList.l_count; i++) {
  966. X        gm = (struct groupmap *) GroupMapList.l_list[i];
  967. X        (void) fprintf(grf, "%s:%s:%d:",
  968. X            gm->gm_name,
  969. X            gm->gm_passwd,
  970. X            gm->gm_gid);
  971. X        listout(&gm->gm_mem, grf);
  972. X        fputs("\n", grf);
  973. X    }
  974. X    (void) fclose(grf);
  975. X    if (rename(GRPTMP, GRPCKP) == -1) {
  976. X        perr(GRPTMP);
  977. X        return;
  978. X    }
  979. X    return;
  980. X}
  981. X
  982. Xckp_cs()
  983. X
  984. X{
  985. X    struct class *cs;
  986. X    register int i;
  987. X    FILE *csf;
  988. X
  989. X    csf = fopen(CSTMP, "w");
  990. X    if (csf == NULL) {
  991. X        perr(CSTMP);
  992. X        return;
  993. X    }
  994. X    for (i=0; i < ClassList.l_count; i++) {
  995. X        cs = (struct class *) ClassList.l_list[i];
  996. X        (void) fprintf(csf, "%s %d %d\n", cs->cs_name, cs->cs_dsize,
  997. X                       cs->cs_exptime);
  998. X        (void) fprintf(csf, "%s", cs->cs_desc);
  999. X    }
  1000. X    (void) fclose(csf);
  1001. X    if (rename(CSTMP, CSCKP) == -1) {
  1002. X        perr(CSTMP);
  1003. X        return;
  1004. X    }
  1005. X    return;
  1006. X}
  1007. X
  1008. Xckp_sg()
  1009. X
  1010. X{
  1011. X    struct sig *sg;
  1012. X    register int i;
  1013. X    FILE *sgf;
  1014. X
  1015. X    sgf = fopen(SIGTMP, "w");
  1016. X    if (sgf == NULL) {
  1017. X        perr(SIGTMP);
  1018. X        return;
  1019. X    }
  1020. X    for (i=0; i < SigList.l_count; i++) {
  1021. X        sg = (struct sig *) SigList.l_list[i];
  1022. X        (void) fprintf(sgf, "%s %d %d\n", sg->sg_name, sg->sg_dsize,
  1023. X                       sg->sg_exptime);
  1024. X        (void) fprintf(sgf, "%s", sg->sg_desc);
  1025. X    }
  1026. X    (void) fclose(sgf);
  1027. X    if (rename(SIGTMP, SIGCKP) == -1) {
  1028. X        perr(SIGTMP);
  1029. X        return;
  1030. X    }
  1031. X    return;
  1032. X}
  1033. X
  1034. Xckp_rg()
  1035. X
  1036. X{
  1037. X    struct range *rg;
  1038. X    register int i;
  1039. X    FILE *rgf;
  1040. X
  1041. X    rgf = fopen(RANGETMP, "w");
  1042. X    if (rgf == NULL) {
  1043. X        perr(RANGETMP);
  1044. X        return;
  1045. X    }
  1046. X    for (i=0; i < RangeList.l_count; i++) {
  1047. X        rg = (struct range *) RangeList.l_list[i];
  1048. X        (void) fprintf(rgf, "%s\t%d\t%d\t%s\n",
  1049. X            rg->rg_name,
  1050. X            rg->rg_from,
  1051. X            rg->rg_to,
  1052. X            (rg->rg_mode == RG_SHARED ? "shared" : "exclusive"));
  1053. X    }
  1054. X    (void) fclose(rgf);
  1055. X    if (rename(RANGETMP, RANGECKP) == -1) {
  1056. X        perr(RANGETMP);
  1057. X        return;
  1058. X    }
  1059. X    return;
  1060. X}
  1061. X
  1062. Xckp_vg()
  1063. X
  1064. X{
  1065. X    register int i;
  1066. X    FILE *vgf;
  1067. X
  1068. X    vgf = fopen(VIGTMP, "w");
  1069. X    if (vgf == NULL) {
  1070. X        perr(VIGTMP);
  1071. X        return;
  1072. X    }
  1073. X    for (i=0; i < Vigs.l_count; i++)
  1074. X        (void) fprintf(vgf, "%s\n", Vigs.l_list[i]);
  1075. X    (void) fclose(vgf);
  1076. X    if (rename(VIGTMP, VIGCKP) == -1) {
  1077. X        perr(VIGTMP);
  1078. X        return;
  1079. X    }
  1080. X    return;
  1081. X}
  1082. X
  1083. Xpanic(reason)
  1084. Xchar *reason;
  1085. X
  1086. X{
  1087. X    err("");
  1088. X    err(reason);
  1089. X    if (ModBits) {
  1090. X        msg("Checkpointing...");
  1091. X        ckpchanges();
  1092. X        err("All changes made to the accounting files");
  1093. X        err("have been checkpointed.");
  1094. X    }
  1095. X    goodbye(1);
  1096. X}
  1097. X
  1098. Xckpchanges()
  1099. X
  1100. X{
  1101. X    /*
  1102. X     * All signals that could cause an unwanted checkpoint are blocked
  1103. X     * here lest file collisions and choas ensue.
  1104. X     */
  1105. X    critical();
  1106. X
  1107. X    (ModBits&PW) && ckp_pw();
  1108. X    (ModBits&AC) && ckp_ac();
  1109. X#ifdef SENDMAIL
  1110. X    (ModBits&AL) && ckp_al();
  1111. X#endif
  1112. X    (ModBits&CS) && ckp_cs();
  1113. X    (ModBits&GR) && ckp_gr();
  1114. X    (ModBits&RG) && ckp_rg();
  1115. X    (ModBits&SG) && ckp_sg();
  1116. X    (ModBits&VG) && ckp_vg();
  1117. X    sync();
  1118. X
  1119. X    non_critical();
  1120. X    return;
  1121. X}
  1122. @//E*O*F src/ckp.c//
  1123. if test 6255 -ne "`wc -c <'src/ckp.c'`"; then
  1124.     echo shar: error transmitting "'src/ckp.c'" '(should have been 6255 characters)'
  1125. fi
  1126. fi # end of overwriting check
  1127. echo shar: extracting "'src/date.c'" '(8068 characters)'
  1128. if test -f 'src/date.c' ; then 
  1129.   echo shar: will not over-write existing file "'src/date.c'"
  1130. else
  1131. sed 's/^X//' >src/date.c <<'@//E*O*F src/date.c//'
  1132. X#include <sys/types.h>
  1133. X#include <sys/time.h>
  1134. X#include <setjmp.h>
  1135. X#include <signal.h>
  1136. X#include <strings.h>
  1137. X#include "macros.h"
  1138. X#include "mem.h"
  1139. X
  1140. X#define DOOMYEAR    2010
  1141. X#define STONEAGES    1975
  1142. X#define DAY        (4*21600)
  1143. X#define ISLEAPYEAR(y)    (((y)%4==0) && (((y)%100!=0) || ((y)%400==0)))
  1144. X
  1145. Xchar    *sprintf(), GET();
  1146. X
  1147. X#ifdef sun
  1148. X#define    sighandler    (void (*)())
  1149. X#else
  1150. X#define    sighandler    (int (*)())
  1151. X#endif
  1152. X
  1153. Xextern    jmp_buf in_continue;
  1154. X#ifdef sun
  1155. Xvoid    tstp_cleanup(), input_continue();
  1156. X#else
  1157. Xint    tstp_cleanup(), input_continue();
  1158. X#endif
  1159. X
  1160. Xstatic     char *days[] = {
  1161. X    "Sunday",    "Monday",    "Tuesday",    "Wednesday",
  1162. X    "Thursday",     "Friday",     "Saturday"
  1163. X};
  1164. X
  1165. Xstatic    char *how_many[] = {
  1166. X    "zero",        "one",        "two",        "three",
  1167. X    "four",        "five",        "six",        "seven",
  1168. X    "eigth",    "nine",        "ten",         "eleven",
  1169. X    "twelve"
  1170. X};
  1171. X
  1172. Xstatic    char *Months[12] = {
  1173. X    "January", "February", "March", "April",
  1174. X    "May", "June", "July", "August",
  1175. X    "September", "October", "November", "December"
  1176. X};
  1177. X
  1178. Xstatic    int DaysInMonths[12] = {
  1179. X    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  1180. X};
  1181. X
  1182. Xtime_t    tmtotime_t();
  1183. X
  1184. Xtime_t
  1185. Xchoosedate(starttime)
  1186. Xtime_t starttime;
  1187. X
  1188. X{
  1189. X    struct tm *t, newt;
  1190. X    time_t time();
  1191. X    char prompt[MEDIUM_BUF], line[MEDIUM_BUF];
  1192. X    register int indx;
  1193. X    int leapday;
  1194. X    char c;
  1195. X
  1196. X    err("Use SPACE to go forward, ^H or DELETE to go backwards.");
  1197. X    err("Hit RETURN to select.");
  1198. X    err("");
  1199. X
  1200. X    if (starttime == (time_t) 0)
  1201. X      starttime = time((time_t *)0);
  1202. X    t = localtime(&starttime);
  1203. X    bcopy(&newt, t, sizeof (struct tm));
  1204. X    prompt[0] = '\0';
  1205. X    /*
  1206. X     * Choose month
  1207. X     */
  1208. X    indx = t->tm_mon;
  1209. X    (void) strcpy(line, Months[indx]);
  1210. X    cbreak();
  1211. X    (void) signal(SIGTSTP, tstp_cleanup);
  1212. X    (void) signal(SIGCONT, input_continue);
  1213. X    (void) setjmp(in_continue);
  1214. X    redraw(prompt, line);
  1215. X    while ((c = GET()) != '\r') {
  1216. X        if (setjmp(in_continue) == SIGCONT) {
  1217. X            redraw(prompt, line);
  1218. X            continue;
  1219. X        }
  1220. X        switch (c) {
  1221. X        case ' ':
  1222. X            indx = (indx+1) % 12;
  1223. X            (void) sprintf(line, "%-9s", Months[indx]);
  1224. X            redraw(prompt, line);
  1225. X            break;
  1226. X        case '\b':
  1227. X        case '\177':
  1228. X            if (--indx < 0)
  1229. X                indx = 11;
  1230. X            (void) sprintf(line, "%-9s", Months[indx]);
  1231. X            redraw(prompt, line);
  1232. X            break;
  1233. X        default:
  1234. X            break;
  1235. X        }
  1236. X    }
  1237. X    (void) strcpy(prompt, Months[indx]);
  1238. X    (void) strcat(prompt, " ");
  1239. X    newt.tm_mon = indx;
  1240. X    indx = t->tm_mday;
  1241. X    if (indx > DaysInMonths[newt.tm_mon])
  1242. X        indx = DaysInMonths[newt.tm_mon];
  1243. X    (void) sprintf(line, "%2d", indx);
  1244. X    (void) setjmp(in_continue);
  1245. X    redraw(prompt, line);
  1246. X    /*
  1247. X     * Choose day of the month.
  1248. X     */
  1249. X    while ((c = GET()) != '\r') {
  1250. X        if (setjmp(in_continue) == SIGCONT) {
  1251. X            redraw(prompt, line);
  1252. X            continue;
  1253. X        }
  1254. X        switch (c) {
  1255. X        case ' ':
  1256. X            if (++indx > DaysInMonths[newt.tm_mon])
  1257. X                indx = 1;
  1258. X            (void) sprintf(line, "%2d", indx);
  1259. X            redraw(prompt, line);
  1260. X            break;
  1261. X        case '\b':
  1262. X        case '\177':
  1263. X            if (--indx < 1)
  1264. X                indx = DaysInMonths[newt.tm_mon];
  1265. X            (void) sprintf(line, "%2d", indx);
  1266. X            redraw(prompt, line);
  1267. X            break;
  1268. X        default:
  1269. X            break;
  1270. X        }
  1271. X    }
  1272. X    (void) strcat(prompt, line);
  1273. X    (void) strcat(prompt, ", ");
  1274. X    newt.tm_mday = indx;
  1275. X    leapday = (newt.tm_mon == 1 && newt.tm_mday == 29);
  1276. X    indx = t->tm_year + 1900;
  1277. X    if (leapday)
  1278. X        indx = nextleapyear(indx);
  1279. X    (void) sprintf(line, "%4d", indx);
  1280. X    /*
  1281. X     * Choose year
  1282. X     */
  1283. X    (void) setjmp(in_continue);
  1284. X    redraw(prompt, line);
  1285. X    while ((c = GET()) != '\r') {
  1286. X        if (setjmp(in_continue) == SIGCONT) {
  1287. X            redraw(prompt, line);
  1288. X            continue;
  1289. X        }
  1290. X        switch (c) {
  1291. X        case ' ':
  1292. X            if (leapday)
  1293. X                indx = nextleapyear(indx);
  1294. X            else if (++indx > DOOMYEAR)
  1295. X                indx = DOOMYEAR;
  1296. X            (void) sprintf(line, "%4d", indx);
  1297. X            redraw(prompt, line);
  1298. X            break;
  1299. X        case '\b':
  1300. X        case '\177':
  1301. X            if (leapday)
  1302. X                indx = lastleapyear(indx);
  1303. X            else if (--indx < STONEAGES)
  1304. X                indx = STONEAGES;
  1305. X            (void) sprintf(line, "%4d", indx);
  1306. X            redraw(prompt, line);
  1307. X            break;
  1308. X        default:
  1309. X            break;
  1310. X        }
  1311. X    }
  1312. X    newt.tm_year = indx - 1900;
  1313. X    newt.tm_hour = 0;
  1314. X    newt.tm_min = 0;
  1315. X    newt.tm_sec = 0;
  1316. X    (void) signal(SIGCONT, sighandler SIG_DFL);
  1317. X    (void) signal(SIGTSTP, sighandler SIG_DFL);
  1318. X    nocbreak();
  1319. X    err("");
  1320. X    return tmtotime_t(&newt);
  1321. X}
  1322. X
  1323. Xtime_t
  1324. Xtmtotime_t(t)
  1325. Xregister struct tm *t;
  1326. X
  1327. X{
  1328. X    time_t newtime;
  1329. X    struct timezone tz;
  1330. X    struct timeval tv;
  1331. X    int year, newyear, i;
  1332. X
  1333. X    newtime = (t->tm_year - 70) * 365 * DAY;
  1334. X    for (i=0; i<t->tm_mon; i++)
  1335. X        newtime += (DaysInMonths[i] * DAY);
  1336. X    newtime += (t->tm_mday * DAY);
  1337. X    newyear = t->tm_year + 1900;
  1338. X    year = 1970;
  1339. X    for (; year < newyear; year++)
  1340. X        if (ISLEAPYEAR(year))
  1341. X            newtime += DAY;
  1342. X    if (!ISLEAPYEAR(newyear) && t->tm_mon > 1)
  1343. X        newtime -= DAY;
  1344. X    /* set for midnight in this timezone and correct for dst shifts */
  1345. X    (void) gettimeofday(&tv, &tz);
  1346. X    newtime += tz.tz_minuteswest * 60 - DAY;
  1347. X    t = localtime(&newtime);
  1348. X    switch (t->tm_hour) {
  1349. X    case 23: newtime += 3600;    break;
  1350. X    case  1: newtime -= 3600;    break;
  1351. X    default: break;
  1352. X    }
  1353. X    return newtime;
  1354. X}
  1355. X
  1356. Xint
  1357. Xnextleapyear(startyear)
  1358. Xint startyear;
  1359. X
  1360. X{
  1361. X    register int year;
  1362. X
  1363. X    year = startyear;
  1364. X    while (++year <= DOOMYEAR) {
  1365. X        if (ISLEAPYEAR(year))
  1366. X            return year;
  1367. X    }
  1368. X    return startyear;
  1369. X}
  1370. X
  1371. Xint
  1372. Xlastleapyear(startyear)
  1373. Xint startyear;
  1374. X
  1375. X{
  1376. X    register int year;
  1377. X
  1378. X    year = startyear;
  1379. X    while (--year >= STONEAGES)
  1380. X        if (ISLEAPYEAR(year))
  1381. X            return year;
  1382. X    return startyear;
  1383. X}
  1384. X
  1385. Xchar *
  1386. Xwhen(then)
  1387. Xtime_t then;
  1388. X
  1389. X{
  1390. X    static char tstr[LONG_BUF], descbuf[MEDIUM_BUF];
  1391. X    char *cp, *description, *ampm;
  1392. X    struct tm *tt, tn, *localtime();
  1393. X    time_t time(), now, tilthen, indx, remainder;
  1394. X
  1395. X    now = time((time_t *)0);
  1396. X    tt = localtime(&now);
  1397. X    bcopy(&tn, tt, sizeof (struct tm));
  1398. X    tt = localtime(&then);
  1399. X    tilthen = then - now;
  1400. X    if (then == 0)
  1401. X        return "never";
  1402. X    if (tilthen >= 365 * DAY)
  1403. X        description = "sometime in the distant future";
  1404. X    else if (tilthen >= 30 * DAY) {
  1405. X        indx = tilthen / (30*DAY);
  1406. X        remainder = (tilthen - indx * 30 * DAY) / DAY;
  1407. X        description = sprintf(descbuf,
  1408. X                "%smore than %s month%s hence",
  1409. X                (remainder < 5) ? "a little " : "",
  1410. X                how_many[indx], S(indx));
  1411. X    }
  1412. X    else if (tilthen >= 7 * DAY) {
  1413. X        indx = tilthen / (7*DAY);
  1414. X        remainder = (tilthen - indx * 7 * DAY) / DAY;
  1415. X        description = sprintf(descbuf,
  1416. X                "%smore than %s week%s hence",
  1417. X                (remainder < 3) ? "a little " : "",
  1418. X                how_many[indx], S(indx));
  1419. X    }
  1420. X    else if (tilthen > DAY)
  1421. X        description = sprintf(descbuf, "this %s",
  1422. X                    days[tt->tm_wday]);
  1423. X    else if (tilthen > -DAY) {
  1424. X        if (tn.tm_wday == tt->tm_wday)
  1425. X            if (tt->tm_hour < 7)
  1426. X                description = "early this morning";
  1427. X            else if (tt->tm_hour < 12)
  1428. X                description = "this morning";
  1429. X            else if (tt->tm_hour < 17)
  1430. X                description = "this afternoon";
  1431. X            else if (tt->tm_hour < 22)
  1432. X                description = "tonight";
  1433. X            else
  1434. X                description = "late tonight";
  1435. X        else if (tilthen > 0)
  1436. X            if (tt->tm_hour < 7)
  1437. X                description = "early tomorrow morning";
  1438. X            else if (tt->tm_hour < 12)
  1439. X                description = "tomorrow morning";
  1440. X            else if (tt->tm_hour < 17)
  1441. X                description = "tomorrow afternoon";
  1442. X            else if (tt->tm_hour < 22)
  1443. X                description = "tomorrow night";
  1444. X            else
  1445. X                description = "late tomorrow night";
  1446. X        else
  1447. X            if (tt->tm_hour < 7)
  1448. X                description = "early yesterday morning";
  1449. X            else if (tt->tm_hour < 12)
  1450. X                description = "yesterday morning";
  1451. X            else if (tt->tm_hour < 17)
  1452. X                description = "yesterday afternoon";
  1453. X            else if (tt->tm_hour < 22)
  1454. X                description = "last night";
  1455. X            else
  1456. X                description = "late last night";
  1457. X    }
  1458. X    else if (tilthen > -7 * DAY) {
  1459. X        description = sprintf(descbuf, "last %s",
  1460. X                    days[tt->tm_wday]);
  1461. X    }
  1462. X    else if (tilthen > -30 * DAY) {
  1463. X        indx = -tilthen / (7*DAY);
  1464. X        remainder = (-tilthen % (7*DAY)) / DAY;
  1465. X        description = sprintf(descbuf,
  1466. X                "%sover %s week%s ago",
  1467. X                remainder < 3 ? "a little " : "",
  1468. X                how_many[indx],
  1469. X                S(indx));
  1470. X    }
  1471. X    else if (tilthen > -365 * DAY) {
  1472. X        indx = -tilthen / (30*DAY);
  1473. X        description = sprintf(descbuf,
  1474. X                "over %s month%s ago", how_many[indx],
  1475. X                S(indx));
  1476. X    }
  1477. X    else
  1478. X        description = "sometime during the Triassic...";
  1479. X#ifdef sun
  1480. X    cp = ctime((long *)&then);
  1481. X#else
  1482. X    cp = ctime(&then);
  1483. X#endif
  1484. X
  1485. X    ampm = (tt->tm_hour < 12) ? "am" : "pm";
  1486. X    if (tt->tm_hour > 12)
  1487. X        tt->tm_hour -= 12;
  1488. X    else if (tt->tm_hour == 0)
  1489. X        tt->tm_hour = 12;
  1490. X
  1491. X    (void) sprintf(tstr, "%d:%02d%s  %.3s. %d, %.4s (%s)",
  1492. X                tt->tm_hour, tt->tm_min, ampm,
  1493. X                cp+4, tt->tm_mday, 
  1494. X                cp+20, description);
  1495. X    return tstr;
  1496. X}
  1497. @//E*O*F src/date.c//
  1498. if test 8068 -ne "`wc -c <'src/date.c'`"; then
  1499.     echo shar: error transmitting "'src/date.c'" '(should have been 8068 characters)'
  1500. fi
  1501. fi # end of overwriting check
  1502. echo shar: extracting "'src/disable.c'" '(621 characters)'
  1503. if test -f 'src/disable.c' ; then 
  1504.   echo shar: will not over-write existing file "'src/disable.c'"
  1505. else
  1506. sed 's/^X//' >src/disable.c <<'@//E*O*F src/disable.c//'
  1507. X#include <sys/types.h>
  1508. X#include <lastlog.h>
  1509. X#include "sysdep.h"
  1510. X#include "mem.h"
  1511. X#include "lists.h"
  1512. X#include "account.h"
  1513. X#include "save.h"
  1514. X
  1515. Xextern    int ModBits;
  1516. X
  1517. Xdisableuser(c, v)
  1518. Xint c;
  1519. Xaddr *v;
  1520. X
  1521. X{
  1522. X    struct account *ac;
  1523. X
  1524. X    if ( c > 2 ) {
  1525. X        err1("%s: too many arguments", (char *)v[0]);
  1526. X        return;
  1527. X    }
  1528. X    if (c != 2) {
  1529. X        err1("usage: %s <user>", (char *)v[0]);
  1530. X        return;
  1531. X    }
  1532. X    ac = getacnam((char *)v[1]);
  1533. X    if (!ac) {
  1534. X        err1("%s: no such user", (char *)v[1]);
  1535. X        return;
  1536. X    }
  1537. X
  1538. X    critical();
  1539. X    FREEMEM((char *)ac->ac_shell);
  1540. X    savestr((char **)&ac->ac_shell, DISABLED_SH);
  1541. X    ModBits |= PW;
  1542. X    puts("disabled");
  1543. X    non_critical();
  1544. X
  1545. X    return;
  1546. X}
  1547. @//E*O*F src/disable.c//
  1548. if test 621 -ne "`wc -c <'src/disable.c'`"; then
  1549.     echo shar: error transmitting "'src/disable.c'" '(should have been 621 characters)'
  1550. fi
  1551. fi # end of overwriting check
  1552. echo shar: extracting "'src/edit.c'" '(613 characters)'
  1553. if test -f 'src/edit.c' ; then 
  1554.   echo shar: will not over-write existing file "'src/edit.c'"
  1555. else
  1556. sed 's/^X//' >src/edit.c <<'@//E*O*F src/edit.c//'
  1557. X#include <strings.h>
  1558. X#include "sysdep.h"
  1559. X#include "macros.h"
  1560. X#include "mem.h"
  1561. X
  1562. Xchar    *getenv();
  1563. X
  1564. Xedit(file)
  1565. Xchar *file;
  1566. X
  1567. X{
  1568. X    char *av[4];
  1569. X    char *term = getenv("TERM");
  1570. X    char *visual = getenv("VISUAL");
  1571. X    char *editor = getenv("EDITOR");
  1572. X    char *which;
  1573. X
  1574. X    if (!visual)
  1575. X        visual = DEF_VISUAL;
  1576. X    if (!editor)
  1577. X        editor = DEF_EDITOR;
  1578. X    if (!term)
  1579. X        term = "dumb";
  1580. X
  1581. X    if (eq(term, "dialup") || eq(term, "dumb"))
  1582. X        which = editor;
  1583. X    else if (eq(term, "network"))
  1584. X        which = editor;
  1585. X    else
  1586. X        which = visual;
  1587. X
  1588. X    av[0] = "shell-escape";
  1589. X    av[1] = which;
  1590. X    av[2] = file;
  1591. X    av[3] = (char *)0;
  1592. X    (void) shellescape(3, (addr *)av);
  1593. X    return;
  1594. X}
  1595. @//E*O*F src/edit.c//
  1596. if test 613 -ne "`wc -c <'src/edit.c'`"; then
  1597.     echo shar: error transmitting "'src/edit.c'" '(should have been 613 characters)'
  1598. fi
  1599. fi # end of overwriting check
  1600. echo shar: extracting "'src/errmsg.c'" '(1741 characters)'
  1601. if test -f 'src/errmsg.c' ; then 
  1602.   echo shar: will not over-write existing file "'src/errmsg.c'"
  1603. else
  1604. sed 's/^X//' >src/errmsg.c <<'@//E*O*F src/errmsg.c//'
  1605. X/**********************************************************************\
  1606. X*                                        *
  1607. X*     errmsg.c                               *
  1608. X*                                        *
  1609. X* Mcp eschews stderr and instead dumps things not wanted on stdout to  *
  1610. X* /dev/tty.  These routines should not be used while in cbreak mode    *
  1611. X* because they change the mode without regard to its previous state.   *
  1612. X*                                        *
  1613. X\**********************************************************************/
  1614. X
  1615. X#include <stdio.h>
  1616. X#include <strings.h>
  1617. X#include "mem.h"
  1618. X
  1619. Xextern    int errno, DevTty;
  1620. Xextern    char *sys_errlist[];
  1621. Xchar    *sprintf();
  1622. X
  1623. Xchar_scr(c)
  1624. Xchar c;
  1625. X
  1626. X{
  1627. X    (void) write(DevTty, &c, 1);
  1628. X    return;
  1629. X}
  1630. X
  1631. Xstr_scr(s)
  1632. Xregister char *s;
  1633. X
  1634. X{
  1635. X    (void) write(DevTty, s, strlen(s));
  1636. X}
  1637. X
  1638. Xmsg(ss)
  1639. Xchar *ss;
  1640. X
  1641. X{
  1642. X    static int old_length;
  1643. X    int i, new_length, hadnewline = 0;
  1644. X    char s[LONG_BUF];
  1645. X
  1646. X    (void) strcpy(s, ss);
  1647. X    new_length = strlen(s);
  1648. X    cbreak();
  1649. X    char_scr('\r');
  1650. X    if (s[new_length-1] == '\n') {
  1651. X        s[new_length-1] = '\0';
  1652. X        hadnewline++;
  1653. X        new_length--;
  1654. X    }
  1655. X    str_scr(s);
  1656. X    if (new_length < old_length) {
  1657. X        for (i=new_length; i<old_length; i++)
  1658. X            char_scr(' ');
  1659. X        for (i=new_length; i<old_length; i++)
  1660. X            char_scr('\b');
  1661. X    }
  1662. X    if (hadnewline) str_scr("\r\n");
  1663. X    nocbreak();
  1664. X    old_length = (hadnewline ? 0 : new_length);
  1665. X    return;
  1666. X}
  1667. X
  1668. Xerr(s)
  1669. Xchar *s;
  1670. X
  1671. X{
  1672. X    char errmsg[LONG_BUF];
  1673. X
  1674. X    (void) sprintf(errmsg, "%s\n", s);
  1675. X    msg(errmsg);
  1676. X    return;
  1677. X}
  1678. X
  1679. Xerr1(fmt, s1)
  1680. Xchar *fmt, *s1;
  1681. X
  1682. X{
  1683. X    char errmsg[LONG_BUF];
  1684. X
  1685. X    (void) sprintf(errmsg, fmt, s1);
  1686. X    (void) strcat(errmsg, "\n");
  1687. X    msg(errmsg);
  1688. X    return;
  1689. X}
  1690. X
  1691. Xerr2(fmt, s1, s2)
  1692. Xchar *fmt, *s1, *s2;
  1693. X
  1694. X{
  1695. X    char errmsg[LONG_BUF];
  1696. X
  1697. X    (void) sprintf(errmsg, fmt, s1, s2);
  1698. X    (void) strcat(errmsg, "\n");
  1699. X    msg(errmsg);
  1700. X    return;
  1701. X}
  1702. X
  1703. Xperr(s)
  1704. Xchar *s;
  1705. X
  1706. X{
  1707. X    err2("%s: %s", s, sys_errlist[errno]);
  1708. X    return;
  1709. X}
  1710. @//E*O*F src/errmsg.c//
  1711. if test 1741 -ne "`wc -c <'src/errmsg.c'`"; then
  1712.     echo shar: error transmitting "'src/errmsg.c'" '(should have been 1741 characters)'
  1713. fi
  1714. fi # end of overwriting check
  1715. echo shar: extracting "'src/exists.c'" '(1531 characters)'
  1716. if test -f 'src/exists.c' ; then 
  1717.   echo shar: will not over-write existing file "'src/exists.c'"
  1718. else
  1719. sed 's/^X//' >src/exists.c <<'@//E*O*F src/exists.c//'
  1720. X#include <sys/file.h>
  1721. X#include <sys/types.h>
  1722. X#include <strings.h>
  1723. X#include <lastlog.h>
  1724. X#include "sysdep.h"
  1725. X#include "mem.h"
  1726. X#include "lists.h"
  1727. X#include "sort.h"
  1728. X#include "account.h"
  1729. X#include "groupmap.h"
  1730. X#include "class.h"
  1731. X#include "sig.h"
  1732. X
  1733. X#ifdef SENDMAIL
  1734. Xextern    struct list Aliases;
  1735. X#endif
  1736. Xextern    struct list AccountList, GroupMapList, Groups, Users;
  1737. Xextern    struct list Classes, Sigs, Ranges, Vigs;
  1738. X
  1739. Xint userexists(s)
  1740. Xchar *s;
  1741. X
  1742. X{
  1743. X    int found;
  1744. X
  1745. X    (void) search_list(&Users, s, strcmp, &found);
  1746. X    return found;
  1747. X}
  1748. X
  1749. Xint groupexists(s)
  1750. Xchar *s;
  1751. X
  1752. X{
  1753. X    int found;
  1754. X
  1755. X    (void) search_list(&Groups, s, strcmp, &found);
  1756. X    return found;
  1757. X}
  1758. X
  1759. Xint classexists(s)
  1760. Xchar *s;
  1761. X
  1762. X{
  1763. X    int found;
  1764. X
  1765. X    (void) search_list(&Classes, s, strcmp, &found);
  1766. X    return found;
  1767. X}
  1768. X
  1769. Xint rangeexists(s)
  1770. Xchar *s;
  1771. X
  1772. X{
  1773. X    int found;
  1774. X
  1775. X    (void) search_list(&Ranges, s, strcmp, &found);
  1776. X    return found;
  1777. X}
  1778. X
  1779. Xint vigexists(s)
  1780. Xchar *s;
  1781. X
  1782. X{
  1783. X    int found;
  1784. X
  1785. X    (void) search_list(&Vigs, s, strcmp, &found);
  1786. X    return found;
  1787. X}
  1788. X
  1789. Xint uidexists(n)
  1790. Xint n;
  1791. X
  1792. X{
  1793. X    int found;
  1794. X
  1795. X    (void) search_list(&AccountList, (char *)&n, iacctcmp, &found);
  1796. X    return found;
  1797. X}
  1798. X
  1799. Xint gidexists(n)
  1800. Xint n;
  1801. X
  1802. X{
  1803. X    int found;
  1804. X
  1805. X    (void) search_list(&GroupMapList, (char *)&n, igmapcmp, &found);
  1806. X    return found;
  1807. X}
  1808. X
  1809. Xsigexists(s)
  1810. Xchar *s;
  1811. X
  1812. X{
  1813. X    int found;
  1814. X
  1815. X    (void) search_list(&Sigs, s, strcmp, &found);
  1816. X    return found;
  1817. X}
  1818. X
  1819. X#ifdef SENDMAIL
  1820. Xaliasexists(name)
  1821. Xchar *name;
  1822. X
  1823. X{
  1824. X    int found;
  1825. X
  1826. X    (void) search_list(&Aliases, name, strcmp, &found);
  1827. X    return found;
  1828. X}
  1829. X#endif SENDMAIL
  1830. X
  1831. Xint
  1832. Xfileexists(file)
  1833. Xchar *file;
  1834. X
  1835. X{
  1836. X    return access(file, F_OK) == -1 ? 0 : 1;
  1837. X}
  1838. @//E*O*F src/exists.c//
  1839. if test 1531 -ne "`wc -c <'src/exists.c'`"; then
  1840.     echo shar: error transmitting "'src/exists.c'" '(should have been 1531 characters)'
  1841. fi
  1842. fi # end of overwriting check
  1843. echo shar: extracting "'src/exit.c'" '(211 characters)'
  1844. if test -f 'src/exit.c' ; then 
  1845.   echo shar: will not over-write existing file "'src/exit.c'"
  1846. else
  1847. sed 's/^X//' >src/exit.c <<'@//E*O*F src/exit.c//'
  1848. X#include "mem.h"
  1849. X#include "lists.h"
  1850. X
  1851. Xextern    struct list Jobs;
  1852. Xextern    int ModBits;
  1853. X
  1854. Xexitmcp()
  1855. X
  1856. X{
  1857. X    if (ModBits || Jobs.l_count)
  1858. X        if (no("There are unsaved changes, exit anyway? [no] "))
  1859. X            return;
  1860. X    goodbye(0);
  1861. X}
  1862. @//E*O*F src/exit.c//
  1863. if test 211 -ne "`wc -c <'src/exit.c'`"; then
  1864.     echo shar: error transmitting "'src/exit.c'" '(should have been 211 characters)'
  1865. fi
  1866. fi # end of overwriting check
  1867. echo shar: extracting "'src/exits.c'" '(483 characters)'
  1868. if test -f 'src/exits.c' ; then 
  1869.   echo shar: will not over-write existing file "'src/exits.c'"
  1870. else
  1871. sed 's/^X//' >src/exits.c <<'@//E*O*F src/exits.c//'
  1872. X#include <stdio.h>
  1873. X#include <strings.h>
  1874. X#include "sysdep.h"
  1875. X#include "mem.h"
  1876. X
  1877. Xextern    int root;
  1878. Xchar    *sprintf();
  1879. X
  1880. Xgoodbye(n)
  1881. Xint n;
  1882. X
  1883. X{
  1884. X    if (root)
  1885. X        unlockpw();
  1886. X    msg("");
  1887. X    nocbreak();
  1888. X    exit(n);
  1889. X}
  1890. X
  1891. Xfatal(s)
  1892. Xchar *s;
  1893. X
  1894. X{
  1895. X    char fatalmsg[LONG_BUF];
  1896. X
  1897. X    (void) sprintf(fatalmsg, "%s\n", s);
  1898. X    msg(fatalmsg);
  1899. X    goodbye(1);
  1900. X}
  1901. X
  1902. Xfatal1(fmt, s1)
  1903. Xchar *fmt, *s1;
  1904. X
  1905. X{
  1906. X    char fatalmsg[LONG_BUF];
  1907. X
  1908. X    (void) sprintf(fatalmsg, fmt, s1);
  1909. X    (void) strcat(fatalmsg, "\n");
  1910. X    msg(fatalmsg);
  1911. X    goodbye(1);
  1912. X    return;
  1913. X}
  1914. @//E*O*F src/exits.c//
  1915. if test 483 -ne "`wc -c <'src/exits.c'`"; then
  1916.     echo shar: error transmitting "'src/exits.c'" '(should have been 483 characters)'
  1917. fi
  1918. fi # end of overwriting check
  1919. echo shar: extracting "'src/freeze.c'" '(3001 characters)'
  1920. if test -f 'src/freeze.c' ; then 
  1921.   echo shar: will not over-write existing file "'src/freeze.c'"
  1922. else
  1923. sed 's/^X//' >src/freeze.c <<'@//E*O*F src/freeze.c//'
  1924. X#include <stdio.h>
  1925. X#include <sys/types.h>
  1926. X#include <lastlog.h>
  1927. X#include "sysdep.h"
  1928. X#include "macros.h"
  1929. X#include "mem.h"
  1930. X#include "lists.h"
  1931. X#include "account.h"
  1932. X#include "groupmap.h"
  1933. X#include "save.h"
  1934. X#include "sort.h"
  1935. X
  1936. X#ifdef BSD4_3
  1937. Xtime_t    time();
  1938. X#endif
  1939. X
  1940. X#define DAY    (4*21600)
  1941. X
  1942. Xextern    struct list AccountList;
  1943. Xextern    int ModBits;
  1944. Xchar    *sprintf(), *when();
  1945. X
  1946. Xfreezeuser(c, v)
  1947. Xint c;
  1948. Xchar **v;
  1949. X
  1950. X{
  1951. X    struct account *ac;
  1952. X    struct groupmap *gm;
  1953. X    char errmsg[LONG_BUF];
  1954. X
  1955. X    if (c != 2) {
  1956. X        err1("usage: %s <user>", (char *)v[0]);
  1957. X        return;
  1958. X    }
  1959. X    ac = getacnam((char *)v[1]);
  1960. X    if (!ac) {
  1961. X        err1("%s: no such user", (char *)v[1]);
  1962. X        return;
  1963. X    }
  1964. X    if (eq(ac->ac_shell, FREEZE_SH)) {
  1965. X        err1("%s: already frozen", (char *)ac->ac_name);
  1966. X        return;
  1967. X    }
  1968. X    gm = getgmgid(ac->ac_gid);
  1969. X    if (!gm) {
  1970. X        (void) sprintf(errmsg,
  1971. X            "no group for gid %d!", ac->ac_gid);
  1972. X        err(errmsg);
  1973. X        return;
  1974. X    }
  1975. X    if (vigexists(gm->gm_name)) {
  1976. X        (void) sprintf(errmsg,
  1977. X            "%s is in vig %s, freeze anyway? [yes] ",
  1978. X            ac->ac_name, gm->gm_name);
  1979. X        if (yes(errmsg) == 0)
  1980. X            return;
  1981. X    }
  1982. X
  1983. X    critical();
  1984. X    FREEMEM((char *)ac->ac_shell);
  1985. X    savestr((char **)&ac->ac_shell, FREEZE_SH);
  1986. X    ModBits |= PW;
  1987. X    puts("frozen");
  1988. X    non_critical();
  1989. X
  1990. X    return;
  1991. X}
  1992. X
  1993. Xfreezeinactives(c, v)
  1994. Xint c;
  1995. Xchar **v;
  1996. X
  1997. X{
  1998. X    struct account *ac;
  1999. X    struct groupmap *gm;
  2000. X    time_t now, toolong, doomsday;
  2001. X    register int indx;
  2002. X    int frozen = 0;
  2003. X
  2004. X    if (c != 2) {
  2005. X        err1("usage: %s <user>", (char *)v[0]);
  2006. X        return;
  2007. X    }
  2008. X    if (!validint((char *)v[1])) {
  2009. X        err2("%s: %s doesn't make sense as a number", (char *)v[0],
  2010. X            (char *)v[1]);
  2011. X        return;
  2012. X    }
  2013. X    now = time((time_t *)0);
  2014. X    toolong = atoi((char *)v[1]) * DAY;
  2015. X    if (toolong <= 0) {
  2016. X        err1("%s: Not bloody likely.", (char *)v[0]);;
  2017. X        return;
  2018. X    }
  2019. X    doomsday = now - toolong;
  2020. X    (void) printf("The axe falls %s\n", when(doomsday));
  2021. X
  2022. X    critical();
  2023. X    for (indx=0; indx < AccountList.l_count; indx++) {
  2024. X        ac = (struct account *) AccountList.l_list[indx];
  2025. X        if (ac->ac_ll.ll_time > doomsday)
  2026. X            continue;
  2027. X        /*
  2028. X         * Don't freeze cryos again.
  2029. X         */
  2030. X        if (eq(ac->ac_shell, FREEZE_SH))
  2031. X            continue;
  2032. X        gm = getgmgid(ac->ac_gid);
  2033. X        if (gm && vigexists(gm->gm_name))
  2034. X                continue;
  2035. X        FREEMEM((char *)ac->ac_shell);
  2036. X        savestr((char **)&ac->ac_shell, FREEZE_SH);
  2037. X        frozen++;
  2038. X    }
  2039. X    if (frozen) {
  2040. X        (void) printf("%d frozen\n", frozen);
  2041. X        ModBits |= PW;
  2042. X    }
  2043. X    else
  2044. X        err("no change");
  2045. X    non_critical();
  2046. X
  2047. X    return;
  2048. X}
  2049. X
  2050. Xfreezedeadbeats()
  2051. X
  2052. X{
  2053. X    struct account *ac;
  2054. X    struct groupmap *gm;
  2055. X    register int indx;
  2056. X    int frozen = 0;
  2057. X
  2058. X    critical();
  2059. X    for (indx=0; indx < AccountList.l_count; indx++) {
  2060. X        ac = (struct account *) AccountList.l_list[indx];
  2061. X        if (ac->ac_classes.l_count || ac->ac_sigs.l_count)
  2062. X            continue;
  2063. X        /*
  2064. X         * Don't freeze cryos again.
  2065. X         */
  2066. X        if (eq(ac->ac_shell, FREEZE_SH))
  2067. X            continue;
  2068. X        gm = getgmgid(ac->ac_gid);
  2069. X        if (gm && vigexists(gm->gm_name))
  2070. X            continue;
  2071. X        FREEMEM((char *)ac->ac_shell);
  2072. X        savestr((char **)&ac->ac_shell, FREEZE_SH);
  2073. X        frozen++;
  2074. X    }
  2075. X    if (frozen) {
  2076. X        (void) printf("%d frozen\n", frozen);
  2077. X        ModBits |= PW;
  2078. X    }
  2079. X    else
  2080. X        err("no change");
  2081. X    non_critical();
  2082. X
  2083. X    return;
  2084. X}
  2085. @//E*O*F src/freeze.c//
  2086. if test 3001 -ne "`wc -c <'src/freeze.c'`"; then
  2087.     echo shar: error transmitting "'src/freeze.c'" '(should have been 3001 characters)'
  2088. fi
  2089. fi # end of overwriting check
  2090. echo shar: extracting "'src/groupmap.c'" '(727 characters)'
  2091. if test -f 'src/groupmap.c' ; then 
  2092.   echo shar: will not over-write existing file "'src/groupmap.c'"
  2093. else
  2094. sed 's/^X//' >src/groupmap.c <<'@//E*O*F src/groupmap.c//'
  2095. X#include "sysdep.h"
  2096. X#include "macros.h"
  2097. X#include "mem.h"
  2098. X#include "lists.h"
  2099. X#include "groupmap.h"
  2100. X
  2101. Xextern    struct list GroupMapList;
  2102. Xextern    int igmapcmp();
  2103. X
  2104. Xstruct groupmap *
  2105. Xgetgmnam(name)
  2106. Xchar *name;
  2107. X
  2108. X{
  2109. X    register int index;
  2110. X    struct groupmap *g;
  2111. X
  2112. X    if (!groupexists(name))
  2113. X        return (struct groupmap *) 0;
  2114. X    for (index=0; index < GroupMapList.l_count; index++) {
  2115. X        g = (struct groupmap *) GroupMapList.l_list[index];
  2116. X        if (eq(g->gm_name, name))
  2117. X            return g;
  2118. X    }
  2119. X    return (struct groupmap *) 0;
  2120. X}
  2121. X
  2122. Xstruct groupmap *
  2123. Xgetgmgid(gid)
  2124. Xint gid;
  2125. X
  2126. X{
  2127. X    int index, found;
  2128. X
  2129. X    index = search_list(&GroupMapList, (char *)&gid, igmapcmp, &found);
  2130. X    if (found)
  2131. X        return (struct groupmap *) GroupMapList.l_list[index];
  2132. X    return (struct groupmap *) 0;
  2133. X}
  2134. @//E*O*F src/groupmap.c//
  2135. if test 727 -ne "`wc -c <'src/groupmap.c'`"; then
  2136.     echo shar: error transmitting "'src/groupmap.c'" '(should have been 727 characters)'
  2137. fi
  2138. fi # end of overwriting check
  2139. echo shar: extracting "'src/groupmap.h'" '(161 characters)'
  2140. if test -f 'src/groupmap.h' ; then 
  2141.   echo shar: will not over-write existing file "'src/groupmap.h'"
  2142. else
  2143. sed 's/^X//' >src/groupmap.h <<'@//E*O*F src/groupmap.h//'
  2144. Xstruct groupmap {
  2145. X    int        gm_gid;
  2146. X    char        *gm_name;
  2147. X    char        *gm_passwd;
  2148. X    struct list    gm_mem;
  2149. X    struct list     gm_aliases;
  2150. X};
  2151. X
  2152. Xstruct groupmap *getgmnam(), *getgmgid();
  2153. @//E*O*F src/groupmap.h//
  2154. if test 161 -ne "`wc -c <'src/groupmap.h'`"; then
  2155.     echo shar: error transmitting "'src/groupmap.h'" '(should have been 161 characters)'
  2156. fi
  2157. fi # end of overwriting check
  2158. echo shar: extracting "'src/history.h'" '(278 characters)'
  2159. if test -f 'src/history.h' ; then 
  2160.   echo shar: will not over-write existing file "'src/history.h'"
  2161. else
  2162. sed 's/^X//' >src/history.h <<'@//E*O*F src/history.h//'
  2163. X#define MAXHIST        40
  2164. X
  2165. Xstruct    hist {
  2166. X    char        *h_line;    /* contents of line */
  2167. X    char        *h_prompt;    /* prompt */
  2168. X    int        h_argc;        /* arg count */
  2169. X    int        h_index;    /* cursor */
  2170. X    int        h_windex;    /* word index */
  2171. X    int        h_qopen;    /* quote open? */
  2172. X    struct list    *h_list;    /* completion list */
  2173. X};
  2174. X
  2175. @//E*O*F src/history.h//
  2176. if test 278 -ne "`wc -c <'src/history.h'`"; then
  2177.     echo shar: error transmitting "'src/history.h'" '(should have been 278 characters)'
  2178. fi
  2179. fi # end of overwriting check
  2180. echo shar: extracting "'src/job.h'" '(242 characters)'
  2181. if test -f 'src/job.h' ; then 
  2182.   echo shar: will not over-write existing file "'src/job.h'"
  2183. else
  2184. sed 's/^X//' >src/job.h <<'@//E*O*F src/job.h//'
  2185. Xstruct    job {
  2186. X    int    jb_todo;
  2187. X    char    *jb_name;
  2188. X    char    *jb_oldname;
  2189. X    int    jb_uid;
  2190. X    int    jb_olduid;
  2191. X    int    jb_gid;
  2192. X    addr    jb_addr;
  2193. X};
  2194. X
  2195. X#define JB_LASTLOG    1
  2196. X#define JB_MKDIR    2
  2197. X#define JB_MV        3
  2198. X#define JB_OMNICHOWN    4
  2199. X#define JB_RMDIR    5
  2200. X#define JB_RMMAIL    6
  2201. @//E*O*F src/job.h//
  2202. if test 242 -ne "`wc -c <'src/job.h'`"; then
  2203.     echo shar: error transmitting "'src/job.h'" '(should have been 242 characters)'
  2204. fi
  2205. fi # end of overwriting check
  2206. echo shar: "End of archive 4 (of 8)."
  2207. cp /dev/null ark4isdone
  2208. DONE=true
  2209. for I in 1 2 3 4 5 6 7 8; do
  2210.     if test -! f ark${I}isdone; then
  2211.         echo "You still need to run archive ${I}."
  2212.         DONE=false
  2213.     fi
  2214. done
  2215. case $DONE in
  2216.     true)
  2217.         echo "You have run all 8 archives."
  2218.         echo 'See the README file'
  2219.         ;;
  2220. esac
  2221. ##  End of shell archive.
  2222. exit 0
  2223.