home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / plp / part10 < prev    next >
Text File  |  1988-09-14  |  50KB  |  2,501 lines

  1. Subject:  v16i023:  Public lineprinter spooler package, Part10/16
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: papowell@julius.cs.umn.edu
  7. Posting-number: Volume 16, Issue 23
  8. Archive-name: plp/part10
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 10 (of 16)."
  17. # Contents:  src/chartable.c src/pac.c utilities/cpr/cpr.c
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'src/chartable.c' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'src/chartable.c'\"
  21. else
  22. echo shar: Extracting \"'src/chartable.c'\" \(14924 characters\)
  23. sed "s/^X//" >'src/chartable.c' <<'END_OF_FILE'
  24. X/***************************************************************************
  25. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  26. X ***************************************************************************
  27. X * MODULE: chartable.c
  28. X * raster character representations
  29. X * Fixed width,
  30. X ***************************************************************************
  31. X * Revision History: Created deep in the bowels of history.
  32. X * $Log:    chartable.c,v $
  33. X * Revision 3.1  88/06/18  09:33:53  papowell
  34. X * Version 3.0- Distributed Sat Jun 18 1988
  35. X * 
  36. X * Revision 2.1  88/05/09  10:07:37  papowell
  37. X * PLP: Released Version
  38. X * 
  39. X * Revision 1.1  88/03/01  11:08:14  papowell
  40. X * Initial revision
  41. X * 
  42. X *        Stolen by everybody.
  43. X *   Fri Jan 15 13:53:37 CST 1988
  44. X ***************************************************************************/
  45. X#ifndef lint
  46. static char id_str1[] =
  47. X    "$Header: chartable.c,v 3.1 88/06/18 09:33:53 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  48. X#endif lint
  49. X
  50. X#define c_______ 0
  51. X#define c______1 01
  52. X#define c_____1_ 02
  53. X#define c____1__ 04
  54. X#define c____11_ 06
  55. X#define c___1___ 010
  56. X#define c___1__1 011
  57. X#define c___1_1_ 012
  58. X#define c___11__ 014
  59. X#define c__1____ 020
  60. X#define c__1__1_ 022
  61. X#define c__1_1__ 024
  62. X#define c__11___ 030
  63. X#define c__111__ 034
  64. X#define c__111_1 035
  65. X#define c__1111_ 036
  66. X#define c__11111 037
  67. X#define c_1_____ 040
  68. X#define c_1____1 041
  69. X#define c_1___1_ 042
  70. X#define c_1__1__ 044
  71. X#define c_1_1___ 050
  72. X#define c_1_1__1 051
  73. X#define c_1_1_1_ 052
  74. X#define c_11____ 060
  75. X#define c_11_11_ 066
  76. X#define c_111___ 070
  77. X#define c_111__1 071
  78. X#define c_111_1_ 072
  79. X#define c_1111__ 074
  80. X#define c_1111_1 075
  81. X#define c_11111_ 076
  82. X#define c_111111 077
  83. X#define c1______ 0100
  84. X#define c1_____1 0101
  85. X#define c1____1_ 0102
  86. X#define c1____11 0103
  87. X#define c1___1__ 0104
  88. X#define c1___1_1 0105
  89. X#define c1___11_ 0106
  90. X#define c1__1___ 0110
  91. X#define c1__1__1 0111
  92. X#define c1__11_1 0115
  93. X#define c1__1111 0117
  94. X#define c1_1____ 0120
  95. X#define c1_1___1 0121
  96. X#define c1_1_1_1 0125
  97. X#define c1_1_11_ 0126
  98. X#define c1_111__ 0134
  99. X#define c1_1111_ 0136
  100. X#define c11____1 0141
  101. X#define c11___1_ 0142
  102. X#define c11___11 0143
  103. X#define c11_1___ 0150
  104. X#define c11_1__1 0151
  105. X#define c111_11_ 0166
  106. X#define c1111___ 0170
  107. X#define c11111__ 0174
  108. X#define c111111_ 0176
  109. X#define c1111111 0177
  110. X
  111. char chartab[][HEIGHT] =    /* this is relatively easy to modify */
  112. X            /* just look: */
  113. X{
  114. X    { c_______,
  115. X      c_______,
  116. X      c_______,
  117. X      c_______,
  118. X      c_______,
  119. X      c_______,
  120. X      c_______,
  121. X      c_______,
  122. X      c_______ },            /*   */
  123. X
  124. X    { c__11___,
  125. X      c__11___,
  126. X      c__11___,
  127. X      c__11___,
  128. X      c__11___,
  129. X      c_______,
  130. X      c_______,
  131. X      c__11___,
  132. X      c__11___ },            /* ! */
  133. X
  134. X    { c_1__1__,
  135. X      c_1__1__,
  136. X      c_______,
  137. X      c_______,
  138. X      c_______,
  139. X      c_______,
  140. X      c_______,
  141. X      c_______,
  142. X      c_______ },            /* " */
  143. X
  144. X    { c_______,
  145. X      c__1_1__,
  146. X      c__1_1__,
  147. X      c1111111,
  148. X      c__1_1__,
  149. X      c1111111,
  150. X      c__1_1__,
  151. X      c__1_1__,
  152. X      c_______ },            /* # */
  153. X
  154. X    { c___1___,
  155. X      c_11111_,
  156. X      c1__1__1,
  157. X      c1__1___,
  158. X      c_11111_,
  159. X      c___1__1,
  160. X      c1__1__1,
  161. X      c_11111_,
  162. X      c___1___ },            /* $ */
  163. X
  164. X     { c_1_____,
  165. X       c1_1___1,
  166. X       c_1___1_,
  167. X       c____1__,
  168. X       c___1___,
  169. X       c__1____,
  170. X       c_1___1_,
  171. X       c1___1_1,
  172. X       c_____1_ },            /* % */
  173. X     { c_11____,
  174. X       c1__1___,
  175. X       c1___1__,
  176. X       c_1_1___,
  177. X       c__1____,
  178. X       c_1_1__1,
  179. X       c1___11_,
  180. X       c1___11_,
  181. X       c_111__1 },            /* & */
  182. X     { c___11__,
  183. X       c___11__,
  184. X       c___1___,
  185. X       c__1____,
  186. X       c_______,
  187. X       c_______,
  188. X       c_______,
  189. X       c_______,
  190. X       c_______ },            /* ' */
  191. X     { c____1__,
  192. X       c___1___,
  193. X       c__1____,
  194. X       c__1____,
  195. X       c__1____,
  196. X       c__1____,
  197. X       c__1____,
  198. X       c___1___,
  199. X       c____1__ },            /* ( */
  200. X     { c__1____,
  201. X       c___1___,
  202. X       c____1__,
  203. X       c____1__,
  204. X       c____1__,
  205. X       c____1__,
  206. X       c____1__,
  207. X       c___1___,
  208. X       c__1____ },            /* ) */
  209. X     { c_______,
  210. X       c___1___,
  211. X       c1__1__1,
  212. X       c_1_1_1_,
  213. X       c__111__,
  214. X       c_1_1_1_,
  215. X       c1__1__1,
  216. X       c___1___,
  217. X       c_______ },            /* * */
  218. X     { c_______,
  219. X       c___1___,
  220. X       c___1___,
  221. X       c___1___,
  222. X       c1111111,
  223. X       c___1___,
  224. X       c___1___,
  225. X       c___1___,
  226. X       c_______ },            /* + */
  227. X     { c_______,
  228. X       c_______,
  229. X       c_______,
  230. X       c_______,
  231. X       c__11___,
  232. X       c__11___,
  233. X       c__1____,
  234. X       c_1_____,
  235. X       c_______ },            /* , */
  236. X     { c_______,
  237. X       c_______,
  238. X       c_______,
  239. X       c_______,
  240. X       c1111111,
  241. X       c_______,
  242. X       c_______,
  243. X       c_______,
  244. X       c_______ },            /* - */
  245. X     { c_______,
  246. X      c_______,
  247. X      c_______,
  248. X      c_______,
  249. X      c_______,
  250. X      c_______,
  251. X      c_______,
  252. X      c__11___,
  253. X      c__11___ },            /* . */
  254. X
  255. X    { c_______,
  256. X      c______1,
  257. X      c_____1_,
  258. X      c____1__,
  259. X      c___1___,
  260. X      c__1____,
  261. X      c_1_____,
  262. X      c1______,
  263. X      c_______ },            /* / */
  264. X
  265. X    { c_11111_,
  266. X      c1_____1,
  267. X      c1____11,
  268. X      c1___1_1,
  269. X      c1__1__1,
  270. X      c1_1___1,
  271. X      c11____1,
  272. X      c1_____1,
  273. X      c_11111_ },            /* 0 */
  274. X
  275. X    { c___1___,
  276. X      c__11___,
  277. X      c_1_1___,
  278. X      c___1___,
  279. X      c___1___,
  280. X      c___1___,
  281. X      c___1___,
  282. X      c___1___,
  283. X      c_11111_ },            /* 1 */
  284. X
  285. X    { c_11111_,
  286. X      c1_____1,
  287. X      c______1,
  288. X      c_____1_,
  289. X      c__111__,
  290. X      c_1_____,
  291. X      c1______,
  292. X      c1______,
  293. X      c1111111 },            /* 2 */
  294. X
  295. X    { c_11111_,
  296. X      c1_____1,
  297. X      c______1,
  298. X      c______1,
  299. X      c__1111_,
  300. X      c______1,
  301. X      c______1,
  302. X      c1_____1,
  303. X      c_11111_ },            /* 3 */
  304. X
  305. X    { c_____1_,
  306. X      c____11_,
  307. X      c___1_1_,
  308. X      c__1__1_,
  309. X      c_1___1_,
  310. X      c1____1_,
  311. X      c1111111,
  312. X      c_____1_,
  313. X      c_____1_ },            /* 4 */
  314. X
  315. X    { c1111111,
  316. X      c1______,
  317. X      c1______,
  318. X      c11111__,
  319. X      c_____1_,
  320. X      c______1,
  321. X      c______1,
  322. X      c1____1_,
  323. X      c_1111__ },            /* 5 */
  324. X
  325. X    { c__1111_,
  326. X      c_1_____,
  327. X      c1______,
  328. X      c1______,
  329. X      c1_1111_,
  330. X      c11____1,
  331. X      c1_____1,
  332. X      c1_____1,
  333. X      c_11111_ },            /* 6 */
  334. X
  335. X    { c1111111,
  336. X      c1_____1,
  337. X      c_____1_,
  338. X      c____1__,
  339. X      c___1___,
  340. X      c__1____,
  341. X      c__1____,
  342. X      c__1____,
  343. X      c__1____ },            /* 7 */
  344. X
  345. X    { c_11111_,
  346. X      c1_____1,
  347. X      c1_____1,
  348. X      c1_____1,
  349. X      c_11111_,
  350. X      c1_____1,
  351. X      c1_____1,
  352. X      c1_____1,
  353. X      c_11111_ },            /* 8 */
  354. X
  355. X    { c_11111_,
  356. X      c1_____1,
  357. X      c1_____1,
  358. X      c1_____1,
  359. X      c_111111,
  360. X      c______1,
  361. X      c______1,
  362. X      c1_____1,
  363. X      c_1111__ },            /* 9 */
  364. X
  365. X    { c_______,
  366. X      c_______,
  367. X      c_______,
  368. X      c__11___,
  369. X      c__11___,
  370. X      c_______,
  371. X      c_______,
  372. X      c__11___,
  373. X      c__11___ },            /* : */
  374. X
  375. X
  376. X    { c__11___,
  377. X      c__11___,
  378. X      c_______,
  379. X      c_______,
  380. X      c__11___,
  381. X      c__11___,
  382. X      c__1____,
  383. X      c_1_____,
  384. X      c_______ },            /* ; */
  385. X
  386. X    { c____1__,
  387. X      c___1___,
  388. X      c__1____,
  389. X      c_1_____,
  390. X      c1______,
  391. X      c_1_____,
  392. X      c__1____,
  393. X      c___1___,
  394. X      c____1__ },            /* < */
  395. X
  396. X    { c_______,
  397. X      c_______,
  398. X      c_______,
  399. X      c1111111,
  400. X      c_______,
  401. X      c1111111,
  402. X      c_______,
  403. X      c_______,
  404. X      c_______ },            /* = */
  405. X
  406. X    { c__1____,
  407. X      c___1___,
  408. X      c____1__,
  409. X      c_____1_,
  410. X      c______1,
  411. X      c_____1_,
  412. X      c____1__,
  413. X      c___1___,
  414. X      c__1____ },            /* > */
  415. X
  416. X    { c__1111_,
  417. X      c_1____1,
  418. X      c_1____1,
  419. X      c______1,
  420. X      c____11_,
  421. X      c___1___,
  422. X      c___1___,
  423. X      c_______,
  424. X      c___1___ },            /* ? */
  425. X
  426. X    { c__1111_,
  427. X      c_1____1,
  428. X      c1__11_1,
  429. X      c1_1_1_1,
  430. X      c1_1_1_1,
  431. X      c1_1111_,
  432. X      c1______,
  433. X      c_1____1,
  434. X      c__1111_ },            /* @ */
  435. X
  436. X    { c__111__,
  437. X      c_1___1_,
  438. X      c1_____1,
  439. X      c1_____1,
  440. X      c1111111,
  441. X      c1_____1,
  442. X      c1_____1,
  443. X      c1_____1,
  444. X      c1_____1 },            /* A */
  445. X
  446. X    { c111111_,
  447. X      c_1____1,
  448. X      c_1____1,
  449. X      c_1____1,
  450. X      c_11111_,
  451. X      c_1____1,
  452. X      c_1____1,
  453. X      c_1____1,
  454. X      c111111_ },            /* B */
  455. X
  456. X    { c__1111_,
  457. X      c_1____1,
  458. X      c1______,
  459. X      c1______,
  460. X      c1______,
  461. X      c1______,
  462. X      c1______,
  463. X      c_1____1,
  464. X      c__1111_ },            /* C */
  465. X
  466. X    { c11111__,
  467. X      c_1___1_,
  468. X      c_1____1,
  469. X      c_1____1,
  470. X      c_1____1,
  471. X      c_1____1,
  472. X      c_1____1,
  473. X      c_1___1_,
  474. X      c11111__ },            /* D */
  475. X
  476. X    { c1111111,
  477. X      c1______,
  478. X      c1______,
  479. X      c1______,
  480. X      c111111_,
  481. X      c1______,
  482. X      c1______,
  483. X      c1______,
  484. X      c1111111 },            /* E */
  485. X
  486. X    { c1111111,
  487. X      c1______,
  488. X      c1______,
  489. X      c1______,
  490. X      c111111_,
  491. X      c1______,
  492. X      c1______,
  493. X      c1______,
  494. X      c1______ },            /* F */
  495. X
  496. X    { c__1111_,
  497. X      c_1____1,
  498. X      c1______,
  499. X      c1______,
  500. X      c1______,
  501. X      c1__1111,
  502. X      c1_____1,
  503. X      c_1____1,
  504. X      c__1111_ },            /* G */
  505. X
  506. X    { c1_____1,
  507. X      c1_____1,
  508. X      c1_____1,
  509. X      c1_____1,
  510. X      c1111111,
  511. X      c1_____1,
  512. X      c1_____1,
  513. X      c1_____1,
  514. X      c1_____1 },            /* H */
  515. X
  516. X    { c_11111_,
  517. X      c___1___,
  518. X      c___1___,
  519. X      c___1___,
  520. X      c___1___,
  521. X      c___1___,
  522. X      c___1___,
  523. X      c___1___,
  524. X      c_11111_ },            /* I */
  525. X
  526. X    { c__11111,
  527. X      c____1__,
  528. X      c____1__,
  529. X      c____1__,
  530. X      c____1__,
  531. X      c____1__,
  532. X      c____1__,
  533. X      c1___1__,
  534. X      c_111___ },            /* J */
  535. X
  536. X    { c1_____1,
  537. X      c1____1_,
  538. X      c1___1__,
  539. X      c1__1___,
  540. X      c1_1____,
  541. X      c11_1___,
  542. X      c1___1__,
  543. X      c1____1_,
  544. X      c1_____1 },            /* K */
  545. X
  546. X    { c1______,
  547. X      c1______,
  548. X      c1______,
  549. X      c1______,
  550. X      c1______,
  551. X      c1______,
  552. X      c1______,
  553. X      c1______,
  554. X      c1111111 },            /* L */
  555. X
  556. X    { c1_____1,
  557. X      c11___11,
  558. X      c1_1_1_1,
  559. X      c1__1__1,
  560. X      c1_____1,
  561. X      c1_____1,
  562. X      c1_____1,
  563. X      c1_____1,
  564. X      c1_____1 },            /* M */
  565. X
  566. X    { c1_____1,
  567. X      c11____1,
  568. X      c1_1___1,
  569. X      c1__1__1,
  570. X      c1___1_1,
  571. X      c1____11,
  572. X      c1_____1,
  573. X      c1_____1,
  574. X      c1_____1 },            /* N */
  575. X
  576. X    { c__111__,
  577. X      c_1___1_,
  578. X      c1_____1,
  579. X      c1_____1,
  580. X      c1_____1,
  581. X      c1_____1,
  582. X      c1_____1,
  583. X      c_1___1_,
  584. X      c__111__ },            /* O */
  585. X
  586. X    { c111111_,
  587. X      c1_____1,
  588. X      c1_____1,
  589. X      c1_____1,
  590. X      c111111_,
  591. X      c1______,
  592. X      c1______,
  593. X      c1______,
  594. X      c1______ },            /* P */
  595. X
  596. X    { c__111__,
  597. X      c_1___1_,
  598. X      c1_____1,
  599. X      c1_____1,
  600. X      c1_____1,
  601. X      c1__1__1,
  602. X      c1___1_1,
  603. X      c_1___1_,
  604. X      c__111_1 },            /* Q */
  605. X
  606. X    { c111111_,
  607. X      c1_____1,
  608. X      c1_____1,
  609. X      c1_____1,
  610. X      c111111_,
  611. X      c1__1___,
  612. X      c1___1__,
  613. X      c1____1_,
  614. X      c1_____1 },            /* R */
  615. X
  616. X    { c_11111_,
  617. X      c1_____1,
  618. X      c1______,
  619. X      c1______,
  620. X      c_11111_,
  621. X      c______1,
  622. X      c______1,
  623. X      c1_____1,
  624. X      c_11111_ },            /* S */
  625. X
  626. X    { c1111111,
  627. X      c___1___,
  628. X      c___1___,
  629. X      c___1___,
  630. X      c___1___,
  631. X      c___1___,
  632. X      c___1___,
  633. X      c___1___,
  634. X      c___1___ },            /* T */
  635. X
  636. X    { c1_____1,
  637. X      c1_____1,
  638. X      c1_____1,
  639. X      c1_____1,
  640. X      c1_____1,
  641. X      c1_____1,
  642. X      c1_____1,
  643. X      c1_____1,
  644. X      c_11111_ },            /* U */
  645. X
  646. X    { c1_____1,
  647. X      c1_____1,
  648. X      c1_____1,
  649. X      c_1___1_,
  650. X      c_1___1_,
  651. X      c__1_1__,
  652. X      c__1_1__,
  653. X      c___1___,
  654. X      c___1___ },            /* V */
  655. X
  656. X    { c1_____1,
  657. X      c1_____1,
  658. X      c1_____1,
  659. X      c1_____1,
  660. X      c1__1__1,
  661. X      c1__1__1,
  662. X      c1_1_1_1,
  663. X      c11___11,
  664. X      c1_____1 },            /* W */
  665. X
  666. X    { c1_____1,
  667. X      c1_____1,
  668. X      c_1___1_,
  669. X      c__1_1__,
  670. X      c___1___,
  671. X      c__1_1__,
  672. X      c_1___1_,
  673. X      c1_____1,
  674. X      c1_____1 },            /* X */
  675. X
  676. X    { c1_____1,
  677. X      c1_____1,
  678. X      c_1___1_,
  679. X      c__1_1__,
  680. X      c___1___,
  681. X      c___1___,
  682. X      c___1___,
  683. X      c___1___,
  684. X      c___1___ },            /* Y */
  685. X
  686. X    { c1111111,
  687. X      c______1,
  688. X      c_____1_,
  689. X      c____1__,
  690. X      c___1___,
  691. X      c__1____,
  692. X      c_1_____,
  693. X      c1______,
  694. X      c1111111 },            /* Z */
  695. X
  696. X    { c_1111__,
  697. X      c_1_____,
  698. X      c_1_____,
  699. X      c_1_____,
  700. X      c_1_____,
  701. X      c_1_____,
  702. X      c_1_____,
  703. X      c_1_____,
  704. X      c_1111__ },            /* [ */
  705. X
  706. X    { c_______,
  707. X      c1______,
  708. X      c_1_____,
  709. X      c__1____,
  710. X      c___1___,
  711. X      c____1__,
  712. X      c_____1_,
  713. X      c______1,
  714. X      c_______ },            /* \ */
  715. X
  716. X    { c__1111_,
  717. X      c_____1_,
  718. X      c_____1_,
  719. X      c_____1_,
  720. X      c_____1_,
  721. X      c_____1_,
  722. X      c_____1_,
  723. X      c_____1_,
  724. X      c__1111_ },            /* ] */
  725. X
  726. X    { c___1___,
  727. X      c__1_1__,
  728. X      c_1___1_,
  729. X      c1_____1,
  730. X      c_______,
  731. X      c_______,
  732. X      c_______,
  733. X      c_______ },            /* ^ */
  734. X
  735. X    { c_______,
  736. X      c_______,
  737. X      c_______,
  738. X      c_______,
  739. X      c_______,
  740. X      c_______,
  741. X      c_______,
  742. X      c1111111,
  743. X      c_______ },            /* _ */
  744. X
  745. X    { c__11___,
  746. X      c__11___,
  747. X      c___1___,
  748. X      c____1__,
  749. X      c_______,
  750. X      c_______,
  751. X      c_______,
  752. X      c_______,
  753. X      c_______ },            /* ` */
  754. X
  755. X    { c_______,
  756. X      c_______,
  757. X      c_______,
  758. X      c_1111__,
  759. X      c_____1_,
  760. X      c_11111_,
  761. X      c1_____1,
  762. X      c1____11,
  763. X      c_1111_1 },            /* a */
  764. X
  765. X    { c1______,
  766. X      c1______,
  767. X      c1______,
  768. X      c1_111__,
  769. X      c11___1_,
  770. X      c1_____1,
  771. X      c1_____1,
  772. X      c11___1_,
  773. X      c1_111__ },            /* b */
  774. X
  775. X    { c_______,
  776. X      c_______,
  777. X      c_______,
  778. X      c_1111__,
  779. X      c1____1_,
  780. X      c1______,
  781. X      c1______,
  782. X      c1____1_,
  783. X      c_1111__ },            /* c */
  784. X
  785. X    { c_____1_,
  786. X      c_____1_,
  787. X      c_____1_,
  788. X      c_111_1_,
  789. X      c1___11_,
  790. X      c1____1_,
  791. X      c1____1_,
  792. X      c1___11_,
  793. X      c_111_1_ },            /* d */
  794. X
  795. X    { c_______,
  796. X      c_______,
  797. X      c_______,
  798. X      c_1111__,
  799. X      c1____1_,
  800. X      c111111_,
  801. X      c1______,
  802. X      c1____1_,
  803. X      c_1111__ },            /* e */
  804. X
  805. X    { c___11__,
  806. X      c__1__1_,
  807. X      c__1____,
  808. X      c__1____,
  809. X      c11111__,
  810. X      c__1____,
  811. X      c__1____,
  812. X      c__1____,
  813. X      c__1____ },            /* f */
  814. X
  815. X    { c_111_1_,
  816. X      c1___11_,
  817. X      c1____1_,
  818. X      c1____1_,
  819. X      c1___11_,
  820. X      c_111_1_,
  821. X      c_____1_,
  822. X      c1____1_,
  823. X      c_1111__ },            /* g */
  824. X
  825. X    { c1______,
  826. X      c1______,
  827. X      c1______,
  828. X      c1_111__,
  829. X      c11___1_,
  830. X      c1____1_,
  831. X      c1____1_,
  832. X      c1____1_,
  833. X      c1____1_ },            /* h */
  834. X
  835. X    { c_______,
  836. X      c___1___,
  837. X      c_______,
  838. X      c__11___,
  839. X      c___1___,
  840. X      c___1___,
  841. X      c___1___,
  842. X      c___1___,
  843. X      c__111__ },            /* i */
  844. X
  845. X    { c____11_,
  846. X      c_____1_,
  847. X      c_____1_,
  848. X      c_____1_,
  849. X      c_____1_,
  850. X      c_____1_,
  851. X      c_____1_,
  852. X      c_1___1_,
  853. X      c__111__ },            /* j */
  854. X
  855. X    { c1______,
  856. X      c1______,
  857. X      c1______,
  858. X      c1___1__,
  859. X      c1__1___,
  860. X      c1_1____,
  861. X      c11_1___,
  862. X      c1___1__,
  863. X      c1____1_ },            /* k */
  864. X
  865. X    { c__11___,
  866. X      c___1___,
  867. X      c___1___,
  868. X      c___1___,
  869. X      c___1___,
  870. X      c___1___,
  871. X      c___1___,
  872. X      c___1___,
  873. X      c__111__ },            /* l */
  874. X
  875. X    { c_______,
  876. X      c_______,
  877. X      c_______,
  878. X      c1_1_11_,
  879. X      c11_1__1,
  880. X      c1__1__1,
  881. X      c1__1__1,
  882. X      c1__1__1,
  883. X      c1__1__1 },            /* m */
  884. X
  885. X    { c_______,
  886. X      c_______,
  887. X      c_______,
  888. X      c1_111__,
  889. X      c11___1_,
  890. X      c1____1_,
  891. X      c1____1_,
  892. X      c1____1_,
  893. X      c1____1_ },            /* n */
  894. X
  895. X    { c_______,
  896. X      c_______,
  897. X      c_______,
  898. X      c_1111__,
  899. X      c1____1_,
  900. X      c1____1_,
  901. X      c1____1_,
  902. X      c1____1_,
  903. X      c_1111__ },            /* o */
  904. X
  905. X    { c1_111__,
  906. X      c11___1_,
  907. X      c1____1_,
  908. X      c1____1_,
  909. X      c11___1_,
  910. X      c1_111__,
  911. X      c1______,
  912. X      c1______,
  913. X      c1______ },            /* p */
  914. X
  915. X    { c_111_1_,
  916. X      c1___11_,
  917. X      c1____1_,
  918. X      c1____1_,
  919. X      c1___11_,
  920. X      c_111_1_,
  921. X      c_____1_,
  922. X      c_____1_,
  923. X      c_____1_ },            /* q */
  924. X
  925. X    { c_______,
  926. X      c_______,
  927. X      c_______,
  928. X      c1_111__,
  929. X      c11___1_,
  930. X      c1______,
  931. X      c1______,
  932. X      c1______,
  933. X      c1______ },            /* r */
  934. X
  935. X    { c_______,
  936. X      c_______,
  937. X      c_______,
  938. X      c_1111__,
  939. X      c1____1_,
  940. X      c_11____,
  941. X      c___11__,
  942. X      c1____1_,
  943. X      c_1111__ },            /* s */
  944. X
  945. X    { c_______,
  946. X      c__1____,
  947. X      c__1____,
  948. X      c11111__,
  949. X      c__1____,
  950. X      c__1____,
  951. X      c__1____,
  952. X      c__1__1_,
  953. X      c___11__ },            /* t */
  954. X
  955. X    { c_______,
  956. X      c_______,
  957. X      c_______,
  958. X      c1____1_,
  959. X      c1____1_,
  960. X      c1____1_,
  961. X      c1____1_,
  962. X      c1___11_,
  963. X      c_111_1_ },            /* u */
  964. X
  965. X    { c_______,
  966. X      c_______,
  967. X      c_______,
  968. X      c1_____1,
  969. X      c1_____1,
  970. X      c1_____1,
  971. X      c_1___1_,
  972. X      c__1_1__,
  973. X      c___1___ },            /* v */
  974. X
  975. X    { c_______,
  976. X      c_______,
  977. X      c_______,
  978. X      c1_____1,
  979. X      c1__1__1,
  980. X      c1__1__1,
  981. X      c1__1__1,
  982. X      c1__1__1,
  983. X      c_11_11_ },            /* w */
  984. X
  985. X    { c_______,
  986. X      c_______,
  987. X      c_______,
  988. X      c1____1_,
  989. X      c_1__1__,
  990. X      c__11___,
  991. X      c__11___,
  992. X      c_1__1__,
  993. X      c1____1_ },            /* x */
  994. X
  995. X    { c1____1_,
  996. X      c1____1_,
  997. X      c1____1_,
  998. X      c1____1_,
  999. X      c1___11_,
  1000. X      c_111_1_,
  1001. X      c_____1_,
  1002. X      c1____1_,
  1003. X      c_1111__ },            /* y */
  1004. X
  1005. X    { c_______,
  1006. X      c_______,
  1007. X      c_______,
  1008. X      c111111_,
  1009. X      c____1__,
  1010. X      c___1___,
  1011. X      c__1____,
  1012. X      c_1_____,
  1013. X      c111111_ },            /* z */
  1014. X
  1015. X    { c___11__,
  1016. X      c__1____,
  1017. X      c__1____,
  1018. X      c__1____,
  1019. X      c_1_____,
  1020. X      c__1____,
  1021. X      c__1____,
  1022. X      c__1____,
  1023. X      c___11__ },            /* } */
  1024. X
  1025. X    { c___1___,
  1026. X      c___1___,
  1027. X      c___1___,
  1028. X      c___1___,
  1029. X      c___1___,
  1030. X      c___1___,
  1031. X      c___1___,
  1032. X      c___1___,
  1033. X      c___1___ },            /* | */
  1034. X
  1035. X    { c__11___,
  1036. X      c____1__,
  1037. X      c____1__,
  1038. X      c____1__,
  1039. X      c_____1_,
  1040. X      c____1__,
  1041. X      c____1__,
  1042. X      c____1__,
  1043. X      c__11___ },            /* } */
  1044. X
  1045. X    { c_11____,
  1046. X      c1__1__1,
  1047. X      c____11_,
  1048. X      c_______,
  1049. X      c_______,
  1050. X      c_______,
  1051. X      c_______,
  1052. X      c_______,
  1053. X      c_______ },            /* ~ */
  1054. X
  1055. X    { c_1__1__,
  1056. X      c1__1__1,
  1057. X      c__1__1_,
  1058. X      c_1__1__,
  1059. X      c1__1__1,
  1060. X      c__1__1_,
  1061. X      c_1__1__,
  1062. X      c1__1__1,
  1063. X      c__1__1_ }            /* rub-out */
  1064. X};
  1065. END_OF_FILE
  1066. if test 14924 -ne `wc -c <'src/chartable.c'`; then
  1067.     echo shar: \"'src/chartable.c'\" unpacked with wrong size!
  1068. fi
  1069. # end of 'src/chartable.c'
  1070. fi
  1071. if test -f 'src/pac.c' -a "${1}" != "-c" ; then 
  1072.   echo shar: Will not clobber existing file \"'src/pac.c'\"
  1073. else
  1074. echo shar: Extracting \"'src/pac.c'\" \(15473 characters\)
  1075. sed "s/^X//" >'src/pac.c' <<'END_OF_FILE'
  1076. X/***************************************************************************
  1077. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  1078. X ***************************************************************************
  1079. X * MODULE: pac.c
  1080. X * Accounting Summary
  1081. X ***************************************************************************
  1082. X * Revision History: Created Thu Feb  4 15:39:38 CST 1988
  1083. X * $Log:    pac.c,v $
  1084. X * Revision 3.1  88/06/18  09:35:14  papowell
  1085. X * Version 3.0- Distributed Sat Jun 18 1988
  1086. X * 
  1087. X * Revision 2.2  88/05/14  10:20:47  papowell
  1088. X * Modified -X flag handling
  1089. X * 
  1090. X * Revision 2.1  88/05/09  10:09:39  papowell
  1091. X * PLP: Released Version
  1092. X * 
  1093. X * Revision 1.6  88/05/05  20:07:32  papowell
  1094. X * Minor changes to shut up lint.
  1095. X * 
  1096. X * Revision 1.5  88/04/15  13:06:00  papowell
  1097. X * Std_environ() call added, to ensure that fd 0 (stdin), 1 (stdout), 2(stderr)
  1098. X * have valid file descriptors;  if not open, then /dev/null is used.
  1099. X * 
  1100. X * Revision 1.4  88/04/07  09:11:50  papowell
  1101. X * Removed redundant break;  strangely, lint did not pick this up
  1102. X * 
  1103. X * Revision 1.3  88/03/25  15:00:57  papowell
  1104. X * Debugged Version:
  1105. X * 1. Added the PLP control file first transfer
  1106. X * 2. Checks for MX during file transfers
  1107. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  1108. X *     apparently they open files and then assume that they will stay
  1109. X *     open.
  1110. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  1111. X * 
  1112. X * Revision 1.2  88/03/11  19:28:52  papowell
  1113. X * Minor Changes, Updates
  1114. X * 
  1115. X * Revision 1.1  88/03/01  11:08:58  papowell
  1116. X * Initial revision
  1117. X * 
  1118. X ***************************************************************************/
  1119. X
  1120. X#ifndef lint
  1121. static char id_str1[] =
  1122. X    "$Header: pac.c,v 3.1 88/06/18 09:35:14 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  1123. X#endif lint
  1124. X#include "lp.h"
  1125. X/***************************************************************************
  1126. X *      pac - printer/ploter accounting information
  1127. X * SYNOPSIS
  1128. X *      pac [ -Pprinter ] [ -pprice ] [ -a ] [ -e ] [ -s ]
  1129. X * DESCRIPTION
  1130. X *      Pac reads the printer/plotter accounting files, accumulating
  1131. X *      the number of pages (the usual case) or feet (for raster
  1132. X *      devices) of paper consumed by each user, and printing out
  1133. X *      how much each user consumed in pages or feet and dollars.
  1134. X *      -Pprinter
  1135. X *           Selects the printer.  If not specified, the value of
  1136. X *           the environment variable PRINTER is used, and if it is
  1137. X *           not defined, the default printer for the site.
  1138. X *      -pprice
  1139. X *           The price per page to be used, instead of the printcap
  1140. X *           co (cost) entry.  If none is specified, the default
  1141. X *           price of $0.02 per page is used.
  1142. X *      -a   Accounting is done for all printers.  A cumulative sum-
  1143. X *           mary of usage of all the entries will be printed.
  1144. X *      -e   Accounting is done for each printer entry in turn.
  1145. X *      -s   Summarize the accounting information in the summary
  1146. X *           accounting file.  Used with the -a or -e flag all the
  1147. X *           accounting information for each printer can be done at
  1148. X *           once.  This option has the side effect of truncating
  1149. X *           the original file.  It copies the original file to a
  1150. X *           backup before doing any action.
  1151. X *      The accounting file is specified in the printcap af entry.
  1152. X *      The summary accounting file has the .sum suffix added.
  1153. X * FILES
  1154. X *      printcap af entry
  1155. X * NOTES
  1156. X *      The accounting information is generated by the various
  1157. X *      filters used by the LPD daemon.  For each user file they
  1158. X *      should write a line to the accounting file in the following
  1159. X *      format.
  1160. X *           user host printer pages format date
  1161. X *           papowell umn-cs 10 C April 13 1988
  1162. X *      The summary file will produce entries of the form:
  1163. X *           user host printer pages format runs cost
  1164. X *           papowell umn-cs 1320 17 32.00
  1165. X ***************************************************************************/
  1166. int    All;            /* do for all printers */
  1167. int Each;            /* do for each printer */
  1168. int Summary;        /* do a summary for each printer */
  1169. int Xpert;
  1170. int Page_price;            /* cost per page to be used */
  1171. float    pagecost = 0.0;            /* cost per page (or what ever) */
  1172. X
  1173. X/*
  1174. X * Hash Table
  1175. X * Each user has his own entry
  1176. X */
  1177. X
  1178. X#define    HASHSIZE    97            /* Number of hash buckets */
  1179. X
  1180. struct entry {
  1181. X    struct entry *next;        /* Forward hash link */
  1182. X    char    user[32];        /* user name */
  1183. X    char    host[32];        /* host name */
  1184. X    char    printer[32];    /* host name */
  1185. X    long    pages;            /* Feet or pages of paper */
  1186. X    char    format[32];        /* format */
  1187. X    long    runs;            /* Number of runs */
  1188. X    float    price;            /* cost for this */
  1189. X    struct entry *chain;    /* list link */
  1190. X};
  1191. X
  1192. struct    entry    *Hash_table[HASHSIZE];    /* Hash table proper */
  1193. struct entry *All_user, *Sum_user, *Raw_user;
  1194. X
  1195. X
  1196. main( argc, argv )
  1197. X    int argc;
  1198. X    char **argv;
  1199. X{
  1200. X    char **list;
  1201. X
  1202. X    /*
  1203. X     * set umask to avoid problems with user umask
  1204. X     */
  1205. X    (void)umask(0);
  1206. X    /*
  1207. X     * Set fd 0, 1, 2 to /dev/null if not open
  1208. X     */
  1209. X    Std_environ();
  1210. X#    ifdef XPERIMENT
  1211. X        Setup_test();
  1212. X#    endif XPERIMENT
  1213. X    /*
  1214. X     * set up the pathnames for information files
  1215. X     */
  1216. X    Tailor_names();
  1217. X
  1218. X    /*
  1219. X     * process the parameters
  1220. X     */
  1221. X    Get_parms(argc, argv);
  1222. X
  1223. X    if( All | Each ){
  1224. X        for( list = All_printers(); *list; ++list ){
  1225. X            Printer = *list;
  1226. X            Process();
  1227. X        }
  1228. X    } else {
  1229. X        Process();
  1230. X    }
  1231. X    if( All ){
  1232. X        Sort_file( &All_user );
  1233. X        Dump_info(All_user, "All");
  1234. X    }
  1235. X}
  1236. X
  1237. X/***************************************************************************
  1238. X * Get_parms()
  1239. X * get the parameters
  1240. X ***************************************************************************/
  1241. static char *optstr = "D:P:Xaep:s";
  1242. Get_parms( argc, argv )
  1243. X    int argc;
  1244. X    char **argv;
  1245. X{
  1246. X    int option;
  1247. X
  1248. X    while( (option = Getopt(argc,argv,optstr)) != EOF ){
  1249. X        switch( option ){
  1250. X        case 'p':
  1251. X            Check_int_dup( option, &Page_price, Optarg );
  1252. X            break;
  1253. X        case 'D':
  1254. X            Check_int_dup( option, &Debug, Optarg );
  1255. X            break;
  1256. X        case 'P':
  1257. X            if( Printer ){
  1258. X                Check_str_dup( option, Printer, Optarg );
  1259. X            }
  1260. X            Printer = Optarg;
  1261. X            break;
  1262. X        case 'X':
  1263. X            Check_dup( option, &Xpert );
  1264. X#            ifdef DEBUG
  1265. X                Setup_test();
  1266. X                Tailor_names();
  1267. X#            else
  1268. X                Diemsg( "-X not allowed" );
  1269. X#            endif DEBUG
  1270. X            break;
  1271. X        case 'e':
  1272. X            Check_dup( option, &Each );
  1273. X            break;
  1274. X        case 'a':
  1275. X            Check_dup( option, &All );
  1276. X            break;
  1277. X        case 's':
  1278. X            Check_dup( option, &Summary );
  1279. X            break;
  1280. X        case '?':
  1281. X            break;
  1282. X        default:
  1283. X            fatal(XLOG_INFO, "Get_parms: badparm %c", option );
  1284. X        }
  1285. X    }
  1286. X
  1287. X    /*
  1288. X     * set up the Parms[] array
  1289. X     */
  1290. X    for( ; Optind < argc; ++Optind ){
  1291. X        if( Parmcount < MAXPARMS ){
  1292. X            Parms[Parmcount].str = argv[Optind];
  1293. X            ++Parmcount;
  1294. X        } else {
  1295. X            Diemsg( "too many files to print; break job up" );
  1296. X        }
  1297. X    }
  1298. X    Get_Printer(0);
  1299. X    /*
  1300. X     * set default format
  1301. X     */
  1302. X    if( FROMHOST[0] == 0 ){
  1303. X        (void)strcpy(FROMHOST, Host);
  1304. X    }
  1305. X    if(Debug>4){
  1306. X        (void)fprintf( stdout, "Printer %s, All %s, Each %s, Summary %s",
  1307. X            Printer, All, Each, Summary );
  1308. X    }
  1309. X}
  1310. X
  1311. X/***************************************************************************
  1312. X * Check_int_dup( int option, int *value, char *arg )
  1313. X * 1.  check to see if value has been set
  1314. X * 2.  if not, then get integer value from arg
  1315. X ***************************************************************************/
  1316. Check_int_dup( option, value, arg )
  1317. X    int option;
  1318. X    int *value;
  1319. X    char *arg;
  1320. X{
  1321. X    if( *value ){
  1322. X        Diemsg( "duplicate option %c", option );
  1323. X    }
  1324. X    if( sscanf( arg, "%d", value ) != 1 || *value <= 0){
  1325. X        Diemsg( "option %c parameter (%s) is not positive integer",
  1326. X            option, arg);
  1327. X    }
  1328. X}
  1329. X/***************************************************************************
  1330. X * Check_str_dup( int option, char *value, char *arg )
  1331. X * 1.  check to see if value has been set
  1332. X * 2.  if not, then set it
  1333. X ***************************************************************************/
  1334. Check_str_dup( option, value, arg )
  1335. X    int option;
  1336. X    char *value;
  1337. X    char *arg;
  1338. X{
  1339. X    if( *value ){
  1340. X        Diemsg( "duplicate option %c", option );
  1341. X    }
  1342. X    if( strlen( arg ) > MAXPARMLEN ){
  1343. X        Diemsg( "option %c arguement too long (%s)", option, arg );
  1344. X    }
  1345. X    (void)strcpy(value, arg );
  1346. X}
  1347. X/***************************************************************************
  1348. X * Check_dup( int option, int *value )
  1349. X * 1.  check to see if value has been set
  1350. X * 2.  if not, then set it
  1351. X ***************************************************************************/
  1352. Check_dup( option, value )
  1353. X    int option;
  1354. X    int *value;
  1355. X{
  1356. X    if( *value ){
  1357. X        Diemsg( "duplicate option %c", option );
  1358. X    }
  1359. X    *value = 1;
  1360. X}
  1361. X
  1362. X
  1363. X/***************************************************************************
  1364. X * Process
  1365. X * Get the accounting file.
  1366. X * 1. Read printcap entry.
  1367. X * 2. Get the accounting file information
  1368. X * 3. If we are to summarize,  read the summyary
  1369. X * 4. Combine the summary and other file information.
  1370. X * 5. if we are to summarize, copy the information to the output summary file
  1371. X *    save the original file, and truncate it.
  1372. X ***************************************************************************/
  1373. Process()
  1374. X{
  1375. X    char buf[BUFSIZ];
  1376. X    FILE *fp, *bp, *sp;        /* Accounting and summary file */
  1377. X
  1378. X    fp = bp = sp = 0;
  1379. X    if(Get_pc_entry(Printer, Status_pc_vars, Status_pc_len) == 0){
  1380. X        Warnmsg("Printer %s does not exist\n", Printer );
  1381. X        return;
  1382. X    }
  1383. X    if( SD == 0 || *SD == 0 ){
  1384. X        if(Debug>2)log(XLOG_DEBUG,"not a Printer");
  1385. X        return;
  1386. X    }
  1387. X    /* chdir to spool directory */
  1388. X    if (chdir(SD) < 0) {
  1389. X        logerr_die( XLOG_NOTICE,"cannot chdir to %s", SD);
  1390. X    }
  1391. X    if( AF == 0 || *AF == 0 ){
  1392. X        Warnmsg("Printer %s does not have accounting file", Printer );
  1393. X        return;
  1394. X    }
  1395. X    if( (fp = fopen( AF, "r+" )) == 0 ){
  1396. X        Warnmsg("Printer %s does not have accounting file", Printer );
  1397. X        return;
  1398. X    }
  1399. X    (void)strcpy(buf, AF );
  1400. X    (void)strcat(buf, ".bac" );
  1401. X    if( (bp = fopen( buf, "w" )) == NULL ){
  1402. X        logerr_die( XLOG_NOTICE,"cannot open backup file %s", buf);
  1403. X    }
  1404. X    if( Summary ){
  1405. X        (void)strcpy(buf, AF );
  1406. X        (void)strcat(buf, ".sum" );
  1407. X        if( (sp = fopen( buf, "r+" )) == NULL ){
  1408. X            logerr_die( XLOG_NOTICE,"cannot open summary file %s", buf);
  1409. X        }
  1410. X    }
  1411. X    Get_raw_file(fp,bp);
  1412. X    if( Summary ){
  1413. X        Get_summary(sp);
  1414. X        Merge_raw_sum();
  1415. X        Sort_file( &Sum_user );
  1416. X        Update_sum(sp);
  1417. X        if( Each ){
  1418. X            Dump_info( Sum_user, Printer );
  1419. X        }
  1420. X    } else if( !All ){
  1421. X        Dump_info( Raw_user, Printer );
  1422. X    }
  1423. X    if( All ){
  1424. X        Merge_raw_all();
  1425. X    }
  1426. X    if( Sum_user ){
  1427. X        Free_entry( Sum_user );
  1428. X        Sum_user = 0;
  1429. X    }
  1430. X    Free_entry( Raw_user );
  1431. X    Raw_user = 0;
  1432. X    if( sp ){
  1433. X        (void)fclose(sp);
  1434. X    }
  1435. X    if( bp ){
  1436. X        (void)fclose(bp);
  1437. X    }
  1438. X    if( fp ){
  1439. X        (void)fclose(fp);
  1440. X    }
  1441. X}
  1442. X
  1443. cleanup()
  1444. X{
  1445. X    exit(1);
  1446. X}
  1447. X/*
  1448. X * Get_raw_file()
  1449. X * read and copy the raw accounting file into the backup,
  1450. X * set up the Raw information
  1451. X */
  1452. X
  1453. Get_raw_file(f, b)
  1454. X    FILE *f, *b;
  1455. X{
  1456. X    char buf[BUFSIZ];
  1457. X    char user[BUFSIZ];
  1458. X    char host[BUFSIZ];
  1459. X    char printer[BUFSIZ];
  1460. X    char format[BUFSIZ];
  1461. X    int  pages;
  1462. X    int  i;
  1463. X    struct entry *p, *Add_entry();
  1464. X    Raw_user = 0;
  1465. X    
  1466. X    Clean_hash();
  1467. X
  1468. X    while( fgets(buf, sizeof(buf), f ) ){
  1469. X        (void)fputs(buf, b);
  1470. X        /* break out the fields */
  1471. X        i = sscanf(buf,"%s %s %s %d %s\n",user,host,printer,&pages,format);
  1472. X        if( i < 4 || strlen(user) > 32 || strlen(host)>32
  1473. X            || pages < 0 || strlen(format)>32){
  1474. X            Warnmsg( "bad format of accounting information: %s\n", buf );
  1475. X        }
  1476. X        p = Add_entry( &Raw_user, user, host, printer, format );
  1477. X        p->pages += pages;
  1478. X        p->runs += 1;
  1479. X    }
  1480. X}
  1481. X/*
  1482. X * Get_summary()
  1483. X * read and copy the raw accounting file into the backup,
  1484. X * set up the Raw information
  1485. X */
  1486. X
  1487. Get_summary(f)
  1488. X    FILE *f;
  1489. X{
  1490. X    char buf[BUFSIZ];
  1491. X    char user[BUFSIZ];
  1492. X    char host[BUFSIZ];
  1493. X    char printer[BUFSIZ];
  1494. X    char format[BUFSIZ];
  1495. X    int  pages;
  1496. X    int  jobs;
  1497. X    int  i;
  1498. X    struct entry *p, *Add_entry();
  1499. X
  1500. X    Sum_user = 0;
  1501. X    
  1502. X    Clean_hash();
  1503. X
  1504. X    while( fgets(buf, sizeof(buf), f ) ){
  1505. X        /* break out the fields */
  1506. X        i = sscanf(buf,"%s %s %s %d %s %d\n",
  1507. X            user,host,printer,&pages,format,&jobs);
  1508. X        if( i < 4 || strlen(user) > 32 || strlen(host)>32
  1509. X            || pages < 0 || strlen(format)>32){
  1510. X            Warnmsg( "bad format of accounting information: %s\n", buf );
  1511. X        }
  1512. X        p = Add_entry( &Sum_user, user, host, printer, format );
  1513. X        p->pages += pages;
  1514. X        p->runs += jobs;
  1515. X    }
  1516. X}
  1517. X
  1518. Clean_hash()
  1519. X{
  1520. X    int i;
  1521. X    for(i = 0; i < HASHSIZE; ++i ){
  1522. X        Hash_table[i] = 0;
  1523. X    }
  1524. X}
  1525. X
  1526. int
  1527. Hash( s )
  1528. X    char *s;
  1529. X{
  1530. X    int i;
  1531. X    
  1532. X    i = s[1]*3 + s[0] + s[strlen(s) -1 ]*7;
  1533. X    return( i % HASHSIZE );
  1534. X}
  1535. X
  1536. struct entry *
  1537. XFind_entry( user, host, printer, format )
  1538. X    char *user, *host, *printer, *format;
  1539. X{
  1540. X    struct entry *p;
  1541. X    int i;
  1542. X
  1543. X    i = Hash( user );
  1544. X
  1545. X    p = Hash_table[i];
  1546. X
  1547. X    while( p ){
  1548. X        if( strcmp(user, p->user ) == 0
  1549. X            && strcmp(host, p->host ) == 0
  1550. X            && strcmp(printer, p->printer ) == 0
  1551. X            && strcmp(format, p->format ) == 0 ){
  1552. X            return(p);
  1553. X        }
  1554. X        p = p->next;
  1555. X    }
  1556. X    return( p );
  1557. X}
  1558. X    
  1559. static struct entry *entry_list;
  1560. X#define NENTRY 25
  1561. X
  1562. struct entry *
  1563. Make_entry( list, user, host, printer, format )
  1564. X    struct entry **list;
  1565. X    char *user, *host, *printer, *format;
  1566. X{
  1567. X    struct entry *p;
  1568. X    static struct entry blank;    /* all zeros */
  1569. X    int i;
  1570. X
  1571. X    if( entry_list == 0 ){
  1572. X        p = entry_list =
  1573. X            (struct entry *)malloc( sizeof(struct entry) * NENTRY );
  1574. X        for( i = 0; i < (NENTRY - 1); ++i ){
  1575. X            p[i].next = &p[i+1];
  1576. X        }
  1577. X        p[i].next = 0;
  1578. X    }
  1579. X    p = entry_list;
  1580. X    entry_list = p->next;
  1581. X
  1582. X    *p = blank;
  1583. X    p->next = 0;
  1584. X    p->chain = 0;
  1585. X        
  1586. X    i = Hash( user );
  1587. X    p->next = Hash_table[i];
  1588. X    Hash_table[i] = p;
  1589. X    (void)strcpy( p->user, user );
  1590. X    (void)strcpy( p->host, host );
  1591. X    (void)strcpy( p->printer, printer );
  1592. X    (void)strcpy( p->format, format );
  1593. X    p->chain = *list;
  1594. X    *list = p;
  1595. X    return( p );
  1596. X}
  1597. X
  1598. XFree_entry( p )
  1599. X    struct entry *p;
  1600. X{
  1601. X    struct entry *q;
  1602. X    while( p ){
  1603. X        q = p->chain;
  1604. X        p->next = entry_list;
  1605. X        entry_list = p;
  1606. X        p = q;
  1607. X    }
  1608. X}
  1609. X
  1610. struct entry *
  1611. Add_entry( list, user, host, printer, format )
  1612. X    struct entry **list;
  1613. X    char *user, *host, *printer;
  1614. X    char *format;
  1615. X{
  1616. X    struct entry *p;
  1617. X    p = Find_entry( user, host, printer, format );
  1618. X    if( p == 0 ){
  1619. X        p = Make_entry( list, user, host, printer, format );
  1620. X    }
  1621. X    return( p );
  1622. X}
  1623. X
  1624. Merge_raw_sum()
  1625. X{
  1626. X    Merge_raw(&Sum_user);
  1627. X}
  1628. Merge_raw_all()
  1629. X{
  1630. X    Merge_raw(&All_user);
  1631. X}
  1632. Merge_raw(s)
  1633. X    struct entry **s;
  1634. X{
  1635. X    struct entry *p, *q;
  1636. X
  1637. X    /*
  1638. X     * assume that you have just read in the summary file
  1639. X     */
  1640. X    p = *s;
  1641. X    while( p ){
  1642. X        q = Make_entry( s, p->user, p->host, p->printer, p->format);
  1643. X        q->runs += p->runs;
  1644. X        q->pages += p->pages;
  1645. X        p = p->chain;
  1646. X    }
  1647. X}
  1648. X
  1649. Update_sum( fp )
  1650. X    FILE *fp;
  1651. X{
  1652. X    struct entry *p;
  1653. X
  1654. X    /*
  1655. X     * next, truncate the file
  1656. X     */
  1657. X    if( ftruncate( fileno(fp), 0 ) < 0 ){
  1658. X        logerr_die( XLOG_INFO, "cannot truncate summary file" );
  1659. X    }
  1660. X    for( p = Sum_user; p; p = p->chain ){
  1661. X        (void)fprintf( fp, "%s %s %s %d %s %d\n", p->user, p->host, p->printer,
  1662. X            p->pages, p->format, p->runs );
  1663. X    }
  1664. X}
  1665. X
  1666. cmpx( l, r )
  1667. X    struct entry **l, **r;
  1668. X{
  1669. X    int c;
  1670. X    struct entry *sl, *sr;
  1671. X    sl = *l;
  1672. X    sr = *r;
  1673. X    if( (c = strcmp( sl->user, sr->user )) == 0
  1674. X     && (c = strcmp( sl->host, sr->host )) == 0 ){
  1675. X        c = strcmp( sl->printer, sr->printer );
  1676. X    }
  1677. X    return( c );
  1678. X}
  1679. Sort_file(st)
  1680. X    struct entry **st;
  1681. X{
  1682. X    int i, n;
  1683. X    struct entry *p, **q;
  1684. X    
  1685. X    /* count the number of entries */
  1686. X    
  1687. X    for( i = 0, p = *st; p; p = p->chain, ++i );
  1688. X    n = i;
  1689. X    if( n > 0 ){
  1690. X        q = (struct entry **)malloc( (unsigned)n*sizeof(struct entry *));
  1691. X        if( q == 0 ){
  1692. X            logerr_die( XLOG_INFO, "malloc failed" );
  1693. X        }
  1694. X        for( i = 0, p = *st; i < n; p = p->chain, ++i ){
  1695. X            q[i] = p;
  1696. X        }
  1697. X        qsort( (char *)q, i, sizeof(struct entry *), cmpx );
  1698. X        for( i = 0; i < n-1;  ++i ){
  1699. X            q[i]->chain = q[i+1];
  1700. X        }
  1701. X        q[i]->chain = 0;
  1702. X    }
  1703. X    
  1704. X}
  1705. X
  1706. Dump_info( p, header )
  1707. X    struct entry *p;
  1708. X    char *header;
  1709. X{
  1710. X    (void)fprintf( stdout, "%s\n", header );
  1711. X    for( ; p; p = p->chain ){
  1712. X        (void)fprintf( stdout, "%s %s %s %d %s %d\n", p->user, p->host, p->printer,
  1713. X            p->pages, p->format, p->runs );
  1714. X    }
  1715. X}
  1716. END_OF_FILE
  1717. if test 15473 -ne `wc -c <'src/pac.c'`; then
  1718.     echo shar: \"'src/pac.c'\" unpacked with wrong size!
  1719. fi
  1720. # end of 'src/pac.c'
  1721. fi
  1722. if test -f 'utilities/cpr/cpr.c' -a "${1}" != "-c" ; then 
  1723.   echo shar: Will not clobber existing file \"'utilities/cpr/cpr.c'\"
  1724. else
  1725. echo shar: Extracting \"'utilities/cpr/cpr.c'\" \(14860 characters\)
  1726. sed "s/^X//" >'utilities/cpr/cpr.c' <<'END_OF_FILE'
  1727. X/*
  1728. X *    This program prints the files named in its argument list, preceding
  1729. X *    the output with a table of contents. Each file is assumed to be C
  1730. X *    source code (but doesn't have to be) in that the program searches
  1731. X *    for the beginning and end of functions. Function names are added to
  1732. X *    the table of contents, provided the name starts at the beginning of
  1733. X *    a line. The function name in the output is double striken.
  1734. X *
  1735. X *    By default blank space is inserted after every closing '}'
  1736. X *    character. Thus functions and structure declarations are nicely
  1737. X *    isolated in the output. The only drawback to this is that structure
  1738. X *    initialization tables sometimes produce lots of white space.
  1739. X *    The "-r" option removes this space, or changes it to the indicated
  1740. X *    length.
  1741. X *
  1742. X *    The option "-l" indicates that the following argument is to be
  1743. X *    the page length used for output (changing the page length hasn't been
  1744. X *    tested much).
  1745. X *
  1746. X *    The option "-s" indicates that the table of contents should be sorted
  1747. X *    by function name within each file.
  1748. X *
  1749. X *    The option "-n" indicates that output lines should be numbered with
  1750. X *    the corresponding line number from the input file.
  1751. X *
  1752. X *    The option "-p" indicates what proportion of the page in steps of 16
  1753. X *    should be used for deciding if a new function needs a new page.
  1754. X *    That is -p12 (the default) indicates that if a function starts
  1755. X *    within the top 12/16 (3/4) of the page then do it, otherwise put it
  1756. X *    on a new page.  Thus the higher the number (upto 16) the closer to
  1757. X *    the bottom of the page will functions be started. -p0 says put each
  1758. X *    func on a new page.
  1759. X *
  1760. X *    Try it! You'll like it. (I call it cpr.c)
  1761. X *
  1762. X *    Written by:
  1763. X *        Paul Breslin
  1764. X *        Human Computing Resources Corp.
  1765. X *        10 St. Mary St.
  1766. X *        Toronto, Ontario
  1767. X *        Canada, M4Y 1P9
  1768. X *
  1769. X *        -- ...!decvax!utcsrgv!hcr!phb
  1770. X *
  1771. X *      Sorting and standard input reading from:
  1772. X *        Rick Wise, CALCULON Corp., Rockville, MD.
  1773. X *        -- ...!decvax!harpo!seismo!rlgvax!cvl!umcp-cs!cal-unix!wise
  1774. X *
  1775. X *    File modified time,
  1776. X *    numbered output,
  1777. X *    optional white space,
  1778. X *    improved function start tests from:
  1779. X *        David Wasley, U.C.Berkeley
  1780. X *        -- ...!ucbvax!topaz.dlw
  1781. X *    Modified the -r to leave variable amounts of space
  1782. X *        Patrick Powell, U. Waterloo
  1783. X *
  1784. X *      Changed handling of form feeds to start a new page AND print heading:
  1785. X *        Terry Doner, U of Waterloo
  1786. X *
  1787. X *    Fixed up to locate more functions, and added -p option
  1788. X *        Dennis Vadura, U of Waterloo
  1789. X *
  1790. X *        It will find things like  struct foo *f()...
  1791. X *        but not things like     int
  1792. X *                    f
  1793. X *                    ()...
  1794. X *        ie. the constraint is that the () must appear on the same line
  1795. X *        as the function name.
  1796. X *
  1797. X *  Clean up a bit for 80286 machines (lints a bit cleaner, too) 
  1798. X *      Dan Frank, Prairie Computing
  1799. X */
  1800. X#include <sys/types.h>
  1801. X#include <sys/stat.h>
  1802. X#include <stdio.h>
  1803. X#include <ctype.h>
  1804. X#include <signal.h>
  1805. X#include <string.h>
  1806. extern int errno;    /* system error number */
  1807. extern char *sys_errlist[];    /* error message */
  1808. extern char *malloc() ;    /* important for 8086-like systems */
  1809. X
  1810. X#define BP        0xC        /* Form feed            */
  1811. X
  1812. X#define TOC_SIZE    4096
  1813. X
  1814. X#define    NEWFILE        1
  1815. X#define NEWFUNCTION    2
  1816. X
  1817. XFILE    *File;
  1818. X
  1819. int    Braces;                /* Keeps track of brace depth    */
  1820. int    LineNumber;            /* Count output lines        */
  1821. int    PageNumber = 0;            /* You figure this one out    */
  1822. int    PageLength = 66;        /* -l <len> Normal paper length    */
  1823. int    PagePart = 12;            /* Decision on paging for new fn*/
  1824. int    PageEnd;            /* Accounts for space at bottom    */
  1825. int    SawFunction;
  1826. int    InComment;
  1827. int    InString;
  1828. X
  1829. long    FileLineNumber;            /* Input file line number    */
  1830. X
  1831. char    *ProgName;
  1832. char    Today[30];
  1833. char    *Name;                /* Current file name        */
  1834. X
  1835. char    FunctionName[80];
  1836. char    FileDate[24];            /* Last modified time of file    */
  1837. X
  1838. char    SortFlag;            /* -s == sort table of contents    */
  1839. char    NumberFlag;            /* -n == output line numbers    */
  1840. int    Space_to_leave = 5;        /* -r<number> space to leave    */
  1841. int    TabWidth = 0;            /* -t <number> width of tabs     */
  1842. X
  1843. main(argc, argv)
  1844. char    **argv;
  1845. X  {
  1846. X    register int    i;
  1847. X    char        *ctime();
  1848. X    time_t        thetime, time();
  1849. X    char        *parm;
  1850. X    int        c;
  1851. X
  1852. X    ProgName = argv[0];
  1853. X    thetime     = time((time_t *)0);
  1854. X    strcpy(Today,ctime(&thetime));
  1855. X
  1856. X    for( i=1; argc > i; ++i )
  1857. X      {
  1858. X        if( argv[i][0] != '-' 
  1859. X        ||  argv[i][1] == '\0' ) break;
  1860. X
  1861. X        parm = argv[i];
  1862. X        while( c = *++parm ) switch( c ){
  1863. X            case 't':
  1864. X            if( argc < 3 ) Usage();
  1865. X            TabWidth = atoi(argv[++i]);
  1866. X            if( TabWidth < 0 )
  1867. X                TabWidth = 0;
  1868. X            break;
  1869. X
  1870. X            case 'l':
  1871. X            if( argc < 3 ) Usage();
  1872. X            PageLength = atoi(argv[++i]);
  1873. X            break;
  1874. X
  1875. X            case 's':
  1876. X            ++SortFlag;
  1877. X            break;
  1878. X
  1879. X            case 'n':
  1880. X            ++NumberFlag;
  1881. X            break;
  1882. X
  1883. X            case 'r':
  1884. X            if( (c = parm[1]) && isdigit( c )
  1885. X                &&( c = atoi( parm+1 )) > 0 ){
  1886. X                Space_to_leave = c;
  1887. X            } else {
  1888. X                Space_to_leave = 0;
  1889. X            }
  1890. X            while( *parm ){
  1891. X                ++parm;
  1892. X            }
  1893. X            --parm;
  1894. X            break;
  1895. X
  1896. X            case 'p':
  1897. X            if( (c = parm[1]) && isdigit( c )
  1898. X                &&( c = atoi( parm+1 )) >= 0 ){
  1899. X                PagePart = (c <= 16) ? c: 16;
  1900. X            }
  1901. X            while( *parm ){
  1902. X                ++parm;
  1903. X            }
  1904. X            --parm;
  1905. X            break;
  1906. X
  1907. X            default:
  1908. X            Usage();
  1909. X            break;
  1910. X          }
  1911. X      }
  1912. X    PageEnd = PageLength - ((PageLength > 30) ? 2 : 1);
  1913. X
  1914. X    StartTempFile();
  1915. X
  1916. X    if( i == argc )
  1917. X      {                /* no file names */
  1918. X        File = stdin;
  1919. X        Name = "Standard Input";
  1920. X        List();
  1921. X      }
  1922. X
  1923. X    for(; i < argc; ++i )
  1924. X      {
  1925. X        if( strcmp(argv[i], "-") == 0 )
  1926. X          {
  1927. X            File = stdin;
  1928. X            Name = "Standard Input";
  1929. X          }
  1930. X        else
  1931. X          {
  1932. X            if( (File = fopen( Name = argv[i], "r" )) == NULL )
  1933. X              {
  1934. X            fprintf(stderr,"%s: Can't open file '%s': %s\n",
  1935. X                    ProgName, Name, sys_errlist[errno] );
  1936. X                continue;
  1937. X              }
  1938. X          }
  1939. X        List();
  1940. X        if( File != stdin ) fclose(File);
  1941. X      }
  1942. X
  1943. X    if( PageNumber > 1 || LineNumber > 0 )
  1944. X        putchar(BP);
  1945. X    EndTempFile();
  1946. X
  1947. X    DumpTableOfContents();
  1948. X    DumpTempFiles();
  1949. X    Done();
  1950. X  }
  1951. X
  1952. Usage()
  1953. X  {
  1954. X    fprintf(stderr, "Usage: %s [-n] [-t tabwidth] [-p[num]] [-r[num]] [-s] [-l pagelength] [files] [-]\n",
  1955. X        ProgName);
  1956. X    exit(1);
  1957. X  }
  1958. X
  1959. int    SaveOut;
  1960. char    *TempName;
  1961. char    *Temp2Name;
  1962. X
  1963. StartTempFile()
  1964. X  {
  1965. X    int        Done();
  1966. X    extern char    *mktemp();
  1967. X
  1968. X    CatchSignalsPlease(Done);
  1969. X
  1970. X    SaveOut  = dup(1);
  1971. X    TempName = mktemp("/tmp/cprXXXXXX");
  1972. X    if( freopen(TempName, "w", stdout) == NULL )
  1973. X      {
  1974. X        fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName,
  1975. X            TempName, sys_errlist[errno]);
  1976. X        exit(1);
  1977. X      }
  1978. X  }
  1979. X
  1980. XEndTempFile()
  1981. X  {
  1982. X    Temp2Name = mktemp("/tmp/CPRXXXXXX");
  1983. X    if( freopen(Temp2Name, "w", stdout) == NULL )
  1984. X      {
  1985. X        fprintf(stderr, "%s: Can't open temp file '%s': %s\n", ProgName,
  1986. X            Temp2Name, sys_errlist[errno]);
  1987. X        exit(1);
  1988. X      }
  1989. X  }
  1990. X
  1991. DumpTempFiles()
  1992. X  {
  1993. X    register int    pid, w;
  1994. X
  1995. X    fclose(stdout);
  1996. X    dup(SaveOut);
  1997. X
  1998. X    while( (pid = fork()) < 0 ) sleep(1);
  1999. X    if( pid )
  2000. X        while ((w = wait((int *)0)) != pid  &&  w != -1);
  2001. X    else
  2002. X      {
  2003. X        CatchSignalsPlease(SIG_DFL);
  2004. X
  2005. X        execl( "/bin/cat", "cat", Temp2Name, TempName, (char *)0 );
  2006. X        fprintf(stderr, "%s: exec of /bin/cat failed: %s\n", ProgName,
  2007. X            sys_errlist[errno]);
  2008. X        exit(0);
  2009. X      }
  2010. X  }
  2011. X
  2012. Done()
  2013. X  {
  2014. X    CatchSignalsPlease(SIG_IGN);
  2015. X
  2016. X    if( TempName )  unlink( TempName );
  2017. X    if( Temp2Name ) unlink( Temp2Name );
  2018. X
  2019. X    exit(0);
  2020. X  }
  2021. X
  2022. CatchSignalsPlease(action)
  2023. int    (*action)();
  2024. X  {
  2025. X    if( signal(SIGINT,  SIG_IGN) != SIG_IGN ) signal(SIGINT,  action);
  2026. X    if( signal(SIGQUIT, SIG_IGN) != SIG_IGN ) signal(SIGQUIT, action);
  2027. X    if( signal(SIGHUP,  SIG_IGN) != SIG_IGN ) signal(SIGHUP,  action);
  2028. X  }
  2029. X
  2030. List()
  2031. X  {
  2032. X    register int    bp;
  2033. X    register char    *bufp;
  2034. X    char        buffer[256];
  2035. X
  2036. X    NewFile();
  2037. X    bp = Braces = 0;
  2038. X    InString = InComment = 0;        /* reset for new file -DV */
  2039. X    SawFunction = 0;
  2040. X    bufp = buffer;
  2041. X    while( fgets(bufp, sizeof(buffer), File) != NULL )
  2042. X      {
  2043. X        ++FileLineNumber;
  2044. X        if( bp )  NewFunction();
  2045. X
  2046. X        if( ++LineNumber >= PageEnd ) NewPage();
  2047. X
  2048. X        if( bufp[0] == '\f'
  2049. X         && bufp[1] == '\n'
  2050. X         && bufp[2] == '\0' ) NewPage(); /* was strcpy(bufp, "^L\n");*/
  2051. X
  2052. X        if( NumberFlag )
  2053. X          {
  2054. X            if( *bufp == '\n' )
  2055. X                printf("        ");
  2056. X            else
  2057. X                printf("%6ld  ", FileLineNumber);
  2058. X          }
  2059. X        if( (Braces == 0) &&  LooksLikeFunction(bufp) )
  2060. X            AddToTableOfContents(NEWFUNCTION);
  2061. X
  2062. X        bp = PutLine(buffer);
  2063. X      }
  2064. X  }
  2065. X
  2066. PutLine(l)
  2067. register char    *l;
  2068. X  {
  2069. X    extern   char    *EndComment();
  2070. X    extern   char    *EndString();
  2071. X    register char    c;
  2072. X    int        bp;
  2073. X    char        *save;
  2074. X
  2075. X    bp = 0;
  2076. X    for( save = l; c = *l; ++l )
  2077. X        if( InComment ) 
  2078. X            l = EndComment(l);
  2079. X        else if( InString )
  2080. X            l = EndString(l);
  2081. X        else
  2082. X            switch(c)
  2083. X              {
  2084. X                case '{':
  2085. X                ++Braces;
  2086. X                break;
  2087. X    
  2088. X                case '}':
  2089. X                if( --Braces == 0 )
  2090. X                    bp = 1;
  2091. X                break;
  2092. X
  2093. X                case '\'':
  2094. X                for( ++l; *l && *l != '\''; ++l )
  2095. X                    if( *l == '\\' && *(l+1) ) ++l;
  2096. X                break;
  2097. X            
  2098. X                case '"':
  2099. X                InString = 1;
  2100. X                break;
  2101. X
  2102. X                case '/':
  2103. X                if( *(l+1) == '*' )
  2104. X                  {
  2105. X                    InComment = 1;
  2106. X                    ++l;
  2107. X                  }
  2108. X                break;
  2109. X              }
  2110. X    printf("%s", save);
  2111. X    return(bp);
  2112. X  }
  2113. X
  2114. char *
  2115. XEndComment(p)
  2116. register char    *p;
  2117. X  {
  2118. X    register char    c;
  2119. X
  2120. X    /*
  2121. X     * Always return pointer to last non-null char looked at.
  2122. X     */
  2123. X    while( c = *p++ )
  2124. X        if( c == '*' && *p == '/' )
  2125. X          {
  2126. X            InComment = 0;
  2127. X            return(p);
  2128. X          }
  2129. X    return(p-2);
  2130. X  }
  2131. X
  2132. char *
  2133. XEndString(p)
  2134. register char    *p;
  2135. X  {
  2136. X    register char    c;
  2137. X
  2138. X    /*
  2139. X     * Always return pointer to last non-null char looked at.
  2140. X     */
  2141. X    while( c = *p++ )
  2142. X        if( c == '\\' && *p )
  2143. X          {
  2144. X            ++p;
  2145. X            continue;
  2146. X          }
  2147. X        else if( c == '"' )
  2148. X          {
  2149. X            InString = 0;
  2150. X            return(p-1);
  2151. X          }
  2152. X    return(p-2);
  2153. X  }
  2154. X
  2155. NewFunction()
  2156. X  {
  2157. X    register int    i;
  2158. X
  2159. X    if( Space_to_leave <= 0 || !SawFunction ) return;
  2160. X    if( LineNumber + Space_to_leave  > (PageLength * PagePart / 16) )
  2161. X        NewPage();
  2162. X    else
  2163. X      {
  2164. X        for( i=0; i < (Space_to_leave); ++i ) putchar('\n');
  2165. X        LineNumber += Space_to_leave;
  2166. X      }
  2167. X
  2168. X    SawFunction = 0;
  2169. X  }
  2170. X
  2171. X#define HEADER_SIZE 3
  2172. X
  2173. NewPage()
  2174. X  {
  2175. X    if( PageNumber >= 0 ) ++PageNumber;
  2176. X    putchar(BP);
  2177. X    LineNumber = 0;
  2178. X
  2179. X    PutHeader();
  2180. X  }
  2181. X
  2182. PutHeader()
  2183. X  {
  2184. X    register int    i, l, j;
  2185. X
  2186. X    putchar('\n');
  2187. X    ++LineNumber;
  2188. X    l = strlen(Name);
  2189. X    for( j=0; j < l; ++j )
  2190. X        printf("%c\b%c\b%c", Name[j], Name[j], Name[j]);
  2191. X
  2192. X    if( PageNumber > 0 )
  2193. X      {
  2194. X        printf("  %.17s", FileDate);
  2195. X        GoToColumn(l+19, 70);
  2196. X        printf("Page:%4d\n\n", PageNumber);
  2197. X        ++LineNumber;
  2198. X        ++LineNumber;
  2199. X      }
  2200. X    else
  2201. X      {
  2202. X        GoToColumn(l, 55);
  2203. X        printf("%s\n\n", Today);
  2204. X        ++LineNumber;
  2205. X        ++LineNumber;
  2206. X      }
  2207. X  }
  2208. X
  2209. GoToColumn(from, to)
  2210. register int    from, to;
  2211. X  {
  2212. X    if( from < to)
  2213. X      {
  2214. X        if( TabWidth > 0 ){
  2215. X            from &= ~(TabWidth-1);
  2216. X            for( ; (from + TabWidth) <= to; from += TabWidth )
  2217. X                putchar('\t');
  2218. X        }
  2219. X        for( ; from < to; from++ )
  2220. X            putchar(' ');
  2221. X      }
  2222. X  }
  2223. X
  2224. X#define isidchr(c)    (isalnum(c) || (c == '_'))
  2225. X
  2226. X/* This used to incorrectly identify a declaration such as
  2227. X *     int (*name[])() = { initializers ... }
  2228. X * as a function.  It also picked up this in an assembler file:
  2229. X *     #define MACRO(x) stuff
  2230. X *     MACRO(x):
  2231. X * Fixed both of these.   -IAN!
  2232. X */
  2233. LooksLikeFunction(s)
  2234. register char    *s;
  2235. X  {
  2236. X    register char    *p;
  2237. X    register int    i;
  2238. X    char        *save;
  2239. X
  2240. X    if( InComment || InString ) return(0);
  2241. X
  2242. X    save = s;
  2243. X
  2244. X    i = 0;
  2245. X    do
  2246. X    {
  2247. X       p = FunctionName;
  2248. X
  2249. X       while( *s && (*s == ' ') || (*s == '\t') ) ++s;
  2250. X       if( *s == '*' ) ++s;
  2251. X       if( !*s || ((*s != '_') && !isalpha(*s)) ) return(0);
  2252. X
  2253. X       while( isidchr(*s) )
  2254. X           *p++ = *s++;
  2255. X       *p = '\0';
  2256. X
  2257. X       while( *s && (*s == ' ') || (*s == '\t') ) ++s;
  2258. X       i++;
  2259. X    }
  2260. X    while ( *s && *s != '(' && i < 4 );
  2261. X
  2262. X    if( *s != '(' || *(s+1) == '*' ) return(0);
  2263. X
  2264. X    for (i = 0; *s; s++)
  2265. X      {
  2266. X        switch( *s )
  2267. X          {
  2268. X            case '(':
  2269. X            ++i;
  2270. X            continue;
  2271. X
  2272. X            case ')':
  2273. X            --i;
  2274. X            break;
  2275. X
  2276. X            default:
  2277. X            break;
  2278. X          }
  2279. X          if( i == 0 ) break;
  2280. X      }
  2281. X    if( !*s ) return(0);
  2282. X
  2283. X    while( *s )
  2284. X      {
  2285. X        if( *s == '{') break;
  2286. X        if( *s == ';' || *s == ':' ) return(0);
  2287. X        ++s;
  2288. X      }
  2289. X
  2290. X    /*
  2291. X     * This will cause the function name part of the line to
  2292. X     * be double striken.  Note that this assumes the name and the opening
  2293. X     * parentheses are on the same line...
  2294. X     */
  2295. X
  2296. X    if( p = strchr( save, '(' ) )
  2297. X    {
  2298. X       p--;
  2299. X       while( p != save && isidchr( *(p-1) ) ) p--;
  2300. X       for( i=0; save != p; save++, i++ ) putchar(' ');
  2301. X       for( ; *p != '('; p++, i++ )       putchar( *p );
  2302. X    }
  2303. X    else
  2304. X       for( i=0; *save && (*save == '*' || isidchr(*save)); ++i, ++save)
  2305. X        if( *save == '*' )
  2306. X            putchar(' ');
  2307. X        else
  2308. X            putchar(*save);
  2309. X
  2310. X    while( i --> 0 ) putchar('\b');
  2311. X
  2312. X    SawFunction = 1;
  2313. X    return(1);
  2314. X  }
  2315. X
  2316. static char    *Toc[TOC_SIZE];
  2317. static int    TocPages[TOC_SIZE];
  2318. static int    TocCount;
  2319. X
  2320. AddToTableOfContents(type)
  2321. X  {
  2322. X    if( TocCount > TOC_SIZE )
  2323. X        return;
  2324. X    if( TocCount == TOC_SIZE )
  2325. X      {
  2326. X        fprintf(stderr, "%s: More than %d Table of contents entries; others ignored.\n",
  2327. X            ProgName, TOC_SIZE);
  2328. X        ++TocCount;
  2329. X        return;
  2330. X      }
  2331. X
  2332. X    if( type == NEWFILE )
  2333. X        AddFile();
  2334. X    else
  2335. X        AddFunction();
  2336. X  }
  2337. X
  2338. AddFunction()
  2339. X  {
  2340. X    register int    l;
  2341. X    register char    *p;
  2342. X
  2343. X    /* This heuristic stops multiple occurrences of a function,
  2344. X     * selected by #ifdefs, to all end up many times over in the
  2345. X     * Table of Contents.  One only needs to see it once.  -IAN!
  2346. X     */
  2347. X    if( TocCount > 0 && TocPages[TocCount-1] == PageNumber
  2348. X        && strcmp(Toc[TocCount-1],FunctionName) == 0 )
  2349. X        return;
  2350. X    l = strlen(FunctionName);
  2351. X    p = Toc[TocCount] = (char *)malloc(l+1);
  2352. X    strcpy(p, FunctionName);
  2353. X    TocPages[TocCount] = PageNumber;
  2354. X    ++TocCount;
  2355. X  }
  2356. X
  2357. AddFile()
  2358. X  {
  2359. X    register int    i, l;
  2360. X    register int    len;
  2361. X    char        temp[20];
  2362. X
  2363. X    len = strlen(Name) + 20;
  2364. X    len = (len < 130) ? 130 : len;
  2365. X    Toc[TocCount] = (char *)malloc(len);
  2366. X    sprintf(Toc[TocCount], "\n    File: %s ", Name);
  2367. X    l = strlen(Toc[TocCount]);
  2368. X    if( l < 64 )
  2369. X      {
  2370. X        if( TabWidth > 0 ){
  2371. X            i = ((64 - l) / TabWidth) + 1;
  2372. X            while( i-- > 0 )
  2373. X                Toc[TocCount][l++] = '\t';
  2374. X        }
  2375. X        else{
  2376. X            while( l < 64 )
  2377. X                Toc[TocCount][l++] = ' ';
  2378. X        }
  2379. X        Toc[TocCount][l++] = '\0';
  2380. X      }
  2381. X    sprintf(temp, "  Page %4d\n", PageNumber);
  2382. X    strcat(Toc[TocCount], temp);
  2383. X    ++TocCount;
  2384. X  }
  2385. X
  2386. NewFile()
  2387. X  {
  2388. X    GetFileTime();
  2389. X    NewPage();
  2390. X    AddToTableOfContents(NEWFILE);
  2391. X    FileLineNumber = 0;
  2392. X  }
  2393. X
  2394. GetFileTime()
  2395. X  {
  2396. X    struct stat    st;
  2397. X
  2398. X    if( File == stdin )
  2399. X        strncpy(FileDate, &Today[4], 20);
  2400. X    else
  2401. X      {
  2402. X        fstat(fileno(File), &st);
  2403. X        strncpy(FileDate, ctime(&st.st_mtime) + 4, 20);
  2404. X      }
  2405. X    strncpy(&FileDate[12], &FileDate[15], 5);
  2406. X    FileDate[18] = '\0';
  2407. X  }
  2408. X
  2409. DumpTableOfContents()
  2410. X  {
  2411. X    register int    i, j;
  2412. X    int         index[TOC_SIZE];
  2413. X
  2414. X    if( TocCount == 0 ) return;
  2415. X
  2416. X    for (i = 0; i < TocCount; i++) index[i] = i;
  2417. X    if( SortFlag )
  2418. X        SortTable(index);
  2419. X
  2420. X    Name = "Table of  Contents";
  2421. X
  2422. X    PageNumber = -1;
  2423. X    LineNumber = 0;
  2424. X    NewPage();
  2425. X
  2426. X    for( i=0; i < TocCount; ++i )
  2427. X      {
  2428. X        if( Toc[index[i]][0] == '\n' )
  2429. X          {
  2430. X            if( (LineNumber + 5) >= PageEnd ) NewPage();
  2431. X
  2432. X            printf("%s", Toc[index[i]]);
  2433. X            LineNumber += 2;
  2434. X            continue;
  2435. X          }
  2436. X        if( ++LineNumber >= PageEnd ) NewPage();
  2437. X
  2438. X        printf("        %s ", Toc[index[i]]);
  2439. X        for( j=strlen(Toc[index[i]]); j < 48; ++j ) putchar('.');
  2440. X        printf(" %4d\n", TocPages[index[i]]);
  2441. X      }
  2442. X  }
  2443. X
  2444. SortTable(index)
  2445. register int    *index;
  2446. X  {
  2447. X    register int    i, temp, flag;
  2448. X
  2449. X    do {
  2450. X        flag = 0;
  2451. X        for (i = 0; i < TocCount - 1; i++)
  2452. X          {
  2453. X            if( Toc[index[i]][0] == '\n' || Toc[index[i+1]][0] == '\n' )
  2454. X                continue;       /* don't sort across file names */
  2455. X            if( strcmp(Toc[index[i]], Toc[index[i+1]]) > 0)
  2456. X              {
  2457. X                temp       = index[i];
  2458. X                index[i]   = index[i+1];
  2459. X                index[i+1] = temp;
  2460. X                flag       = 1;
  2461. X              }
  2462. X          }
  2463. X    } while( flag );
  2464. X  }
  2465. X
  2466. X
  2467. END_OF_FILE
  2468. if test 14860 -ne `wc -c <'utilities/cpr/cpr.c'`; then
  2469.     echo shar: \"'utilities/cpr/cpr.c'\" unpacked with wrong size!
  2470. fi
  2471. # end of 'utilities/cpr/cpr.c'
  2472. fi
  2473. echo shar: End of archive 10 \(of 16\).
  2474. cp /dev/null ark10isdone
  2475. MISSING=""
  2476. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2477.     if test ! -f ark${I}isdone ; then
  2478.     MISSING="${MISSING} ${I}"
  2479.     fi
  2480. done
  2481. if test "${MISSING}" = "" ; then
  2482.     echo You have unpacked all 16 archives.
  2483.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2484. else
  2485.     echo You still need to unpack the following archives:
  2486.     echo "        " ${MISSING}
  2487. fi
  2488. ##  End of shell archive.
  2489. exit 0
  2490.  
  2491.