home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / cmds / root.3 / usr / lib / acct / runacct / runacct~
Text File  |  1998-08-19  |  14KB  |  470 lines

  1. #!/sbin/sh
  2.  
  3. # Copyright (c) 1998 The Santa Cruz Operation, Inc.. All Rights Reserved. 
  4. #                                                                         
  5. #        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF THE               
  6. #                   SANTA CRUZ OPERATION INC.                             
  7. #                                                                         
  8. #   The copyright notice above does not evidence any actual or intended   
  9. #   publication of such source code.                                      
  10.  
  11. #    copyright    "%c%"
  12.  
  13. #!/sbin/sh
  14.  
  15.  
  16. #ident    "@(#)acct:common/cmd/acct/runacct.sh    1.9.1.9"
  17. #ident "$Header: $"
  18. #       "nitely accounting shell, should be run from cron (adm) at 4am"
  19. #    "does process, connect, disk, and fee accounting"
  20. #    "prepares command summaries"
  21. #    "shell is restartable and provides reasonable diagnostics"
  22. _adm=/var/adm
  23. _nite=/var/adm/acct/nite
  24. _sum=/var/adm/acct/sum
  25. _wtmp=/var/adm/wtmp
  26. export PATH
  27. PATH=/usr/lib/acct:/usr/bin:/usr/sbin
  28. _statefile=${_nite}/statefile
  29. _active=${_nite}/active
  30. _lastdate=${_nite}/lastdate
  31. _errormsg="\n\n************ ACCT ERRORS : see  ${_active}${_date}********\n\n"
  32. _MIN_BLKS=500
  33.  
  34. cd ${_adm}
  35. #        "make sure that 2 crons weren't started, or leftover problems"
  36. date  > ${_nite}/lock1
  37. chmod 400 ${_nite}/lock1
  38. ln ${_nite}/lock1 ${_nite}/lock
  39. if test $? -ne 0; then
  40.     _lnkerr="\n\n*********** 2 CRONS or ACCT PROBLEMS***********\n\n\n"
  41.     (date ; echo "$_lnkerr" ) >/dev/console
  42.     echo "$_lnkerr" | mail adm root
  43.     echo "ERROR: locks found, run aborted" >> ${_active}
  44.     rm -f ${_nite}/lock*
  45.     exit 1
  46. fi
  47.  
  48. # Check to see if there is enough space in /var to do nitely accounting
  49. #
  50. _blocks=`df /var | sed "s/.*:  *\([0-9][0-9]*\) blocks.*/\1/"`
  51. if [ "$_blocks" -le $_MIN_BLKS ];then
  52.     echo "runacct: Insufficient space in /var ($_blocks blks); \c"
  53.     echo "Terminating procedure"
  54.     ( echo "runacct: Insufficient space in /var ($_blocks blks); \c"
  55.     echo "Terminating procedure" ) | \
  56.          tee /dev/console ${_active} | mail root adm
  57.     rm -f ${_nite}/lock*
  58.     exit 1
  59. fi
  60.  
  61.  
  62. case $# in
  63. 0)
  64. #    "as called by the cron each day"
  65.     _date="`date +%m%d`"
  66.     if test ! -r ${_lastdate} ; then
  67.         nulladm ${_lastdate}
  68.         echo "0000" > ${_lastdate}
  69.     fi
  70.     if test "${_date}" = "`cat ${_lastdate}`"; then
  71.         (date; echo "${_errormsg}") > /dev/console
  72.         echo "${_errormsg}" | mail root adm
  73.         echo "ERROR: acctg already run for `date`: check ${_lastdate}" >> ${_active}
  74.         rm -f ${_nite}/lock*
  75.         mv ${_active} ${_active}${_date}
  76.         exit 1
  77.     fi
  78.     echo ${_date} > ${_lastdate}
  79.     nulladm ${_statefile}
  80.     echo "SETUP" > ${_statefile}
  81.     nulladm ${_active}
  82.     echo ${_date} > ${_active}    # debuging
  83.     echo "\n\n\n\n\n**********  SYSTEM ACCOUNTING STARTED `date`  **********\n\n\n\n\n" > /dev/console
  84.     echo ${_date} > ${_active}    # debuging
  85.     ;;
  86.  
  87. 1)
  88. #    "runacct MMDD  (date)  will restart at current state"
  89.     _date=$1
  90.     echo "restarting acctg for ${_date} at `cat ${_statefile}`" >> ${_active}
  91.     echo "\n\n\n\n\n********** SYSTEM ACCOUNTING RESTARTED `date` **********\n\n\n\n\n" > /dev/console
  92.     ;;
  93.  
  94. 2)
  95. #    "runacct MMDD STATE  restart at specified state"
  96.     _date=$1
  97.     echo "restarting acctg for ${_date} at $2" >> ${_active}
  98.     echo "previous state was `cat ${_statefile}`" >> ${_active}
  99.     echo "$2" > ${_statefile}
  100.     echo "\n\n\n\n\n********** SYSTEM ACCOUNTING RESTARTED `date` **********\n\n\n\n\n" > /dev/console
  101.     ;;
  102. *)
  103.     (date; echo "${_errormsg}") > /dev/console
  104.     echo "${_errormsg}" | mail root adm
  105.     echo "ERROR: runacct called with invalid arguments" > ${_active}
  106.     rm -f ${_nite}/lock*
  107.     mv ${_active} ${_active}${_date}
  108.     exit 1
  109.     ;;
  110. esac
  111.  
  112. if test ! -r ${_sum}/rprt${_date} ; then
  113.     nulladm ${_sum}/rprt${_date}
  114. fi
  115. if test ! -r ${_nite}/daytacct ; then
  116.     nulladm ${_nite}/daytacct
  117. fi
  118.  
  119. #    "processing is broken down into seperate, restartable states"
  120. #    "the statefile is updated at the end of each state so that the"
  121. #    "next loop through the while statement switches to the next state"
  122. while [ 1 ]
  123. do
  124. case "`cat ${_statefile}`" in
  125. SETUP)
  126.  
  127. cd ${_adm}
  128.  
  129. (date ; ls -l fee pacct* ${_wtmp}* ) >> ${_active}
  130.  
  131. #    "switch current pacct file"
  132. turnacct switch
  133. _rc=$?
  134. if test ${_rc} -ne 0; then
  135.     (date ; echo "${_errormsg}" ) > /dev/console
  136.     echo "${_errormsg}" | mail root adm
  137.     echo "ERROR: turnacct switch returned rc=${_rc}" >> ${_active}
  138.     rm -f ${_nite}/lock*
  139.     mv ${_active} ${_active}${_date}
  140.     exit 1
  141. fi
  142.  
  143. #    " give pacct files unique names for easy restart "
  144. for _i in pacct?*
  145. do
  146.     if test -r S${_i}.${_date} ; then
  147.          (date ; echo "${_errormsg}" ) > /dev/console
  148.         echo "${_errormsg}" | mail root adm
  149.         echo "ERROR: S${_i}.${_date} already exists" >> ${_active}
  150.         echo "file setups probably already run" >> ${_active}
  151.         rm -f ${_nite}/lock*
  152.         mv ${_active} ${_active}${_date}
  153.         exit 1
  154.     fi
  155.     mv ${_i} S${_i}.${_date}
  156. done
  157.  
  158.  
  159. #    "add current time on end"
  160. if test -r ${_nite}/wtmp.${_date} ; then
  161.     (date ; echo "${_errormsg}" ) > /dev/console
  162.     echo "${_errormsg}" | mail root adm
  163.     echo "ERROR: ${_nite}/wtmp.${_date} already exists: run setup manually" > ${_active}
  164.     rm -f ${_nite}/lock*
  165.     mv ${_active} ${_active}${_date}
  166.     exit 1
  167.     nulladm ${_nite}/wtmp.${_date}
  168. fi
  169. closewtmp    # fudge a DEAD_PROCESS for /var/adm/wtmp
  170. cp ${_wtmp} ${_nite}/wtmp.${_date}
  171. acctwtmp "runacct" >> ${_nite}/wtmp.${_date}
  172. nulladm ${_wtmp}
  173. acctwtmp "runacct" >> ${_wtmp}
  174. utmp2wtmp    # fudge active user from utmp to wtmp
  175.  
  176. echo "files setups complete" >> ${_active}
  177. echo "WTMPFIX" > ${_statefile}
  178. ;;
  179.  
  180. WTMPFIX)
  181. #    "verify the integrity of the wtmp file"
  182. #    "wtmpfix will automatically fix date changes"
  183. cd ${_nite}
  184. nulladm tmpwtmp wtmperror
  185. wtmpfix < wtmp.${_date} > tmpwtmp 2>wtmperror
  186. if test $? -ne 0 ; then
  187.     (date ; echo "${_errormsg}") | mail root adm
  188.     echo "${_errormsg}" > /dev/console
  189.     echo "ERROR: wtmpfix errors see ${_nite}/wtmperror${_date}" >> ${_active}
  190.     rm -f ${_nite}/lock*
  191.     mv ${_active} ${_active}${_date}
  192.     mv wtmperror wtmperror${_date}
  193.     exit 1
  194. fi
  195.  
  196. echo "wtmp processing complete" >> ${_active}
  197. echo "CONNECT" > ${_statefile}
  198. ;;
  199.  
  200.  
  201. CONNECT)
  202. #    "produce connect records"
  203. #    "the lineuse and reboots files are used by prdaily"
  204. cd ${_nite}
  205. nulladm lineuse reboots log ctacct.${_date}
  206. acctcon -l lineuse -o reboots < tmpwtmp  2> log > ctacct.${_date}
  207. _rc=$?
  208. if test -s log ; then 
  209.     fmtmsg -u console "`echo "${_errormsg}"`"
  210.     cat ${_nite}/log >> ${_active}
  211.     (date ; cat ${_nite}/log) | mail adm root
  212.     if test ${_rc} -eq 0 ; then
  213.         # if this test is true, then pnpsplit complained about
  214.         # the year and holidays not being up to date.
  215.         # This used to be a fatal error, but now it will
  216.         # continue to process the accounting.
  217.         fmtmsg -u console "     holiday file error in acctcon"
  218.     fi
  219.     if test ${_rc} -eq 4 ; then
  220.         # acctcon ran out of room to account for all users
  221.         # accounting completed for users we had room for
  222.         # nonfatal error
  223.         fmtmsg -u console "     connect accounting incomplete"
  224.     fi
  225.     if test ${_rc} -eq 2 ; then
  226.         # bad records, types or times encountered
  227.         # nonfatal error
  228.         fmtmsg -u console "     bad records encountered by acctcon"
  229.     fi
  230.     if test ${_rc} -eq 3 ; then
  231.         # could not complete connect acctg due to not enough
  232.         # room to store tty line names
  233.         # fatal error
  234.         fmtmsg -u console "Terminating procedure"
  235.         rm -f ${_nite}/lock*
  236.         mv ${_active} ${_active}${_date}
  237.         exit 3
  238.     fi
  239. fi
  240.  
  241. echo "connect acctg complete" >> ${_active}
  242. echo "PROCESS" > ${_statefile}
  243. ;;
  244.  
  245.  
  246. PROCESS)
  247. #    "correlate Spacct and ptacct files by number"
  248. #    "will not process Spacct file if corresponding ptacct exists"
  249. #    "remove the ptacct file to rurun the Spacct file"
  250. #    "if death occurs here, rerunacct should remove last ptacct file"
  251.  
  252. cd ${_nite}
  253. for _Spacct in ${_adm}/Spacct*.${_date}
  254. do
  255.     _ptacct=`basename ${_Spacct} | sed 's/Sp/pt/'`
  256.     if test -s ${_ptacct}; then
  257.         echo "WARNING: accounting already run for ${_Spacct}" \
  258.             >> ${_active}
  259.         echo "WARNING: remove ${_nite}/${_ptacct} to rerun" \
  260.             >> ${_active}
  261.     else
  262.         nulladm ${_ptacct}
  263.         acctprc < ${_Spacct} > ${_ptacct}
  264.     
  265.         echo "process acctg complete for ${_Spacct}" >> ${_active}
  266.     fi
  267. done
  268. echo "all process actg complete for ${_date}" >> ${_active}
  269. echo "MERGE" > ${_statefile}
  270. ;;
  271.  
  272.  
  273. MERGE)
  274. cd ${_nite}
  275. #    "merge ctacct and ptacct files together"
  276. acctmerg ptacct*.${_date} < ctacct.${_date} > daytacct
  277.  
  278. echo "tacct merge to create daytacct complete" >> ${_active}
  279. echo "FEES" > ${_statefile}
  280. ;;
  281.  
  282.  
  283. FEES)
  284. cd ${_nite}
  285. #    "merge in fees"
  286. if test -s ${_adm}/fee; then
  287.     cp daytacct tmpdayt
  288.     sort +0n +2 ${_adm}/fee | acctmerg -i | acctmerg tmpdayt  > daytacct
  289.     echo "merged fees" >> ${_active}
  290.     rm -f tmpdayt
  291. else
  292.     echo "no fees" >> ${_active}
  293. fi
  294. echo "DISK" > ${_statefile}
  295. ;;
  296.  
  297.  
  298. DISK)
  299. cd ${_nite}
  300. #    "the last act of any disk acct procedure should be to mv its"
  301. #    "entire output file to disktacct, where it will be picked up"
  302. if test -r disktacct; then
  303.     cp daytacct tmpdayt
  304.     acctmerg disktacct  < tmpdayt > daytacct
  305.     echo "merged disk records" >> ${_active}
  306.     rm -f tmpdayt
  307.     mv disktacct /tmp/disktacct.${_date}
  308. else
  309.     echo "no disk records" >> ${_active}
  310. fi
  311. echo "MERGETACCT" > ${_statefile}
  312. ;;
  313.  
  314. MERGETACCT)
  315. cd ${_adm}/acct
  316. #    "save each days tacct file in sum/tacct.${_date}"
  317. #    "if sum/tacct gets corrupted or lost, could recreate easily"
  318. #    "the monthly acctg procedure should remove all sum/tacct files"
  319. nulladm sum/tacct${_date}
  320. cp nite/daytacct sum/tacct${_date}
  321. if test ! -r sum/tacct; then
  322.     echo "WARNING: recreating ${_adm}/sum/tacct " >> ${_active}
  323.     nulladm sum/tacct sum/tacctprev
  324. fi
  325.  
  326. #    "merge in todays tacct with the summary tacct"
  327. cp sum/tacct sum/tacctprev
  328. if test -s sum/tacctprev
  329. then    
  330.     acctmerg sum/tacctprev  <sum/tacct${_date} >sum/tacct
  331. else
  332.     acctmerg <sum/tacct${_date} >sum/tacct
  333. fi
  334.  
  335. echo "updated sum/tacct" >> ${_active}
  336. echo "CMS" > ${_statefile}
  337. ;;
  338.  
  339.  
  340. CMS)
  341. cd ${_adm}/acct
  342. #    "do command summaries"
  343. nulladm sum/daycms
  344. if test ! -r sum/cms; then
  345.     nulladm sum/cms sum/cmsprev nite/daycms nite/cms
  346.     echo "WARNING: recreating ${_adm}/sum/cms " >> ${_active}
  347. fi
  348. cp sum/cms sum/cmsprev
  349. acctcms ${_adm}/Spacct*.${_date}  > sum/daycms
  350. acctcms -s sum/daycms sum/cmsprev  > sum/cms
  351. acctcms -a -s sum/daycms | sed -n 1,56p  > nite/daycms
  352. acctcms -a -s sum/cms | sed -n 1,56p  > nite/cms
  353. lastlogin 
  354. echo "command summaries complete" >> ${_active}
  355. echo "USEREXIT" > ${_statefile}
  356. ;;
  357.  
  358.  
  359. USEREXIT)
  360. #    "any installation dependant accounting programs should be run here"
  361. [ -s /usr/lib/acct/runacct.local ] && /usr/lib/acct/runacct.local
  362.  
  363. echo "CLEANUP" > ${_statefile}
  364. ;;
  365.  
  366.  
  367. CLEANUP)
  368. cd ${_adm}/acct
  369. #    " finally clear files; could be done next morning if desired"
  370. nulladm ${_adm}/fee
  371. rm -f ${_adm}/Spacct*.${_date}
  372. #    "put reports onto a file"
  373. prdaily >> sum/rprt${_date};
  374. rm -f nite/lock*
  375. rm -f nite/ptacct*.${_date} nite/ctacct.${_date}
  376. mv nite/wtmp.${_date} nite/owtmp
  377. rm -f nite/wtmperror${_date} nite/active${_date} nite/tmpwtmp
  378. echo "system accounting completed at `date`" >> ${_active}
  379. mv ${_active} ${_active}${_date}
  380. echo "********** SYSTEM ACCOUNTING COMPLETED `date` **********" > /dev/console
  381. echo "COMPLETE" > ${_statefile}
  382. exit 0
  383. ;;
  384.  
  385. *)
  386.     (date;echo "${_errormsg}") > /dev/console
  387.     echo "${_errormsg}" | mail adm root
  388.     echo "ERROR: invalid state, check ${_statefile}" >> ${_active}
  389.     rm -f ${_nite}/lock*
  390.     mv ${_active} ${_active}${_date}
  391.     exit 1
  392.     ;;
  393. esac
  394. done
  395.  
  396.  
  397. #    " runacct is normally called with no arguments from the cron"
  398. #    " it checks its own locks to make sure that 2 crons or previous"
  399. #    " problems have not occured"
  400.  
  401. #    " runacct uses the statefile to record its progress"
  402. #    " each state updates the statefile upon completion"
  403. #    " then the next loop though the while picks up the new state"
  404.  
  405. #    " to restart this shell,  check the active file for diagnostics"
  406. #    " fix up any corrupted data (ie. bad pacct or wtmp files)"
  407. #    " if runacct detected the error it removes the locks"
  408. #    " remove the locks if necessary, otherwise runacct will complain"
  409. #    " the lastdate file should be removed or changed"
  410. #    " restart runacct at current state with:  runacct MMDD"
  411. #    " to override the statefile: runacct MMDD STATE"
  412.  
  413.  
  414. #    " if runacct has been executed after the latest failure"
  415. #    " ie. it ran ok today but failed yesterday"
  416. #    " the statefile will not be correct"
  417. #    " check the active files and restart properly"
  418.  
  419. #    " if runacct failed in the PROCESS state, remove the last"
  420. #    " ptacct file because it may not be complete"
  421.  
  422. #    " if shell has failed several days, do SETUP manually"
  423. #    " then rerun runacct once for each day failed"
  424. #    " could use fwtmp here to split up wtmp file correctly"
  425.  
  426. #    " normally not a good idea to restart the SETUP state"
  427. #    " should be done manually, or just cleanup first"
  428.  
  429.  
  430. #    " FILE USAGE:    all files in /var/adm/acct/nite unless specified"
  431.  
  432. #    " statefile    records progess of runacct"
  433. #    " lastdate    last day runacct ran in date +%m%d format"
  434. #    " lock lock1    controls serial use of runacct"
  435. #    " active    place for all descriptive and error messages"
  436. #    " fd2log    fd2 output for runacct ( see cron entry ) "
  437. #    " wtmp.MMDD owtmp yesterdays wtmp file"
  438. #    " tmpwtmp    yesterdays wtmp corrected by wtmpfix"
  439. #    " wtmperror    place for wtmpfix error messages"
  440. #    " lineuse    lineusage report used in prdaily"
  441. #    " reboots    reboots report used in prdaily"
  442. #    " log        place for error messages from acctcon1"
  443. #    " ctacct.MMDD    connect tacct records for MMDD"
  444. #    " ptacct.n.MMDD    process tacct records n files for MMDD"
  445. #    " daytacct    total tacct records for this days accounting"
  446. #    " disktacct    disk tacct records produced by disk shell"
  447. #    " daycms    ascii daily command summary used by prdaily"
  448. #    " cms        acsii total command summary used by prdaily"
  449.  
  450. #    " following files in /var/adm directory"
  451.  
  452. #    " fee        output from chargefee program"
  453. #    " pacct        active pacct file"
  454. #    " pacctn    switched pacct files"
  455. #    " Spacctn.MMDD    pacct files for MMDD after SETUP state"
  456. #    " wtmp        active wtmp file"
  457.  
  458. #    " following files in /var/adm/acct/sum"
  459.  
  460. #    " loginlog    output of lastlogin used in prdaily"
  461. #    " tacct        total tacct file for current fiscal"
  462. #    " tacct.MMDD    tacct file for day MMDD"
  463. #    " cms        total cms file for current fiscal"
  464. #    " rprt.MMDD    output of prdaily program"
  465. #    " wtmp.MMDD    saved copy of wtmp for MMDD"
  466. #    " pacct.MMDD    concatenated version of all pacct files for MMDD"
  467. #    " cmsprev    total cms file without latest update"
  468. #    " tacctprev    total tacct file without latest update"
  469. #    " daycms    cms files for todays usage"
  470.