home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2378 < prev    next >
Internet Message Format  |  1990-12-28  |  18KB

  1. From: purdon@athena.mit.edu (James R. Purdon III)
  2. Newsgroups: alt.sources
  3. Subject: slugnet - Multiple user conferencing system: Part 3 of 6
  4. Message-ID: <1990Dec20.164451.25293@athena.mit.edu>
  5. Date: 20 Dec 90 16:44:51 GMT
  6.  
  7. The slugnet program is a multiple-user, interactive conferencing
  8. facility.  It currently runs under a variety of System V-based and
  9. BSD-based operating systems (although certain functions may not be
  10. possible under some of these operating systems).
  11.  
  12. Cut here-------------------------------------------------------------------
  13.  
  14. #!/bin/sh
  15. # to extract, remove the header and type "sh filename"
  16. if `test ! -s ./slugnet.doc`
  17. then
  18. echo "writing ./slugnet.doc"
  19. cat > ./slugnet.doc << '\End\Of\Shar\'
  20. .TL
  21. @(#)slugnet.doc    1.2 
  22.  
  23. .AU
  24. James Purdon
  25. .LP
  26. .B Introduction
  27. .LP
  28. The slugnet program is a multiple-user, interactive conferencing
  29. facility.  It currently runs under SUNOS, UNICOS, and ULTRIX, as well as
  30. on machines running UNIX System V 2.x and 3.x (although certain
  31. functions may not be possible under some of these operating systems).
  32.  
  33. .B History
  34. .LP
  35. I first got the idea for slugnet in 1985, after a short viewing of RELAY, the
  36. BITNET conferencing facility.  Although I had written a multiple-user
  37. conferencing facility with multiple channels, private conferences,
  38. conference locking, and paging under the MUSIC/SP operating system at the
  39. University of Georgia, something about the RELAY format inspired me to
  40. write a short program (in FORTG1) which had some of the look and feel of
  41. RELAY. 
  42. .PP
  43. Of course, user-written talk programs weren't exactly encouraged at UGA,
  44. so I played with it a bit, showed it to a few folks, and then abandoned
  45. it.  That code may still be lurking about on one of my PC floppies, but
  46. it is for the most part lost.
  47. .PP
  48. In 1986 I gained access to another machine, a Control Data Corporation
  49. Cyber 180/865 running NOS 2.x (my memory is a bit hazy here).  In order
  50. to understand it better, I decided to write a conferencing system in FTN5
  51. similar to the one I had done before on MUSIC.  Again, I showed it to a
  52. few folks, but there was little interest.  There were already some
  53. system programs that were functionally equivalent, which ran with great
  54. efficiency on the system's NPUs.  After setting up the program in a
  55. script that would automatically build it, I again abandoned it (however,
  56. the code to this version is a part of this package and is in the file
  57. slugnet.n).
  58. .PP
  59. Shortly after I had completed the FTN5 version, I obtained a copy of
  60. Microsoft Quick C for my PC XT in order to learn c.  At the time I was
  61. running a multiple-user, multitasking OS on my PC called Wendin Dos, and
  62. I decided for a lark to port slugnet to c.  
  63. .PP
  64. Late in 1987 I was able to upgrade my PC XT to a PC AT and for the
  65. first time I was able to run UNIX.  Again I ported slugnet as a learning
  66. experience.  
  67. .PP
  68. Since then, I have ported slugnet just about every time I have learned a
  69. new operating system or encountered a different hardware platform.  Its
  70. been quite helpful in illustrating where a particular UNIX-variant is
  71. different from what I'm accustomed too.  The latest modifications I've
  72. made allow it to run as a server under TCP/IP, so that users do not
  73. require a login in order to use it.
  74. .PP
  75. Well its a new decade and I have grand new ideas for another program.
  76. It seems a shame to waste the effort I put into slugnet, and I really
  77. like the name, so I thought I'd post it to the net for posterity.
  78.  
  79. .B "How slugnet Works"
  80. .LP
  81. Slugnet uses files, lots of files.  One for each active user, a central
  82. directory,
  83. and files for things like file-locking, news and command definitions.
  84. Each time a
  85. user tries to read incoming messages, there is a disk access.  Every
  86. time a user writes a message, there is a disk access for each recipient.
  87. If the user selects to read messages continuously, there is a disk
  88. access each interval specified by the "set delay" command.  If you are
  89. on a system with fast i/o, you won't be bothered, but otherwise you may
  90. suffer a performance penalty.  
  91. .PP
  92. There is a local program "slugnet" and a network server "slugnetd".
  93. Neither requires the other to be present, and both use the same files
  94. for communication.  If you don't want to service the net, you don't have
  95. to.
  96. .PP
  97. By default, slugnet is setuid to whatever account owns slugnet.  I
  98. recommend creating its own account rather than using root.  It is setuid
  99. to protect the privacy of user messages and to keep malicious users from
  100. wreaking havoc.  You could try to use ignorance to protect the files, if
  101. you don't want to run it setuid.
  102. .PP
  103. Running slugnet setuid brings up some problems.  There are a series of
  104. commands the user can execute to do things like save configurations,
  105. message buffers, and incoming messages, run slugnet scripts, and read in
  106. files to be transmitted as messages (of course none of these commands
  107. make sense for users of the network server and should not be
  108. permitted).
  109. In UNIX System V a user process may switch back and forth between the
  110. real and effective uid but under some BSD-based systems this is not
  111. possible. Under these systems it is necessary to limit what the user
  112. may do (in fact, it is the default state for all systems).
  113. .PP
  114. Slugnet controls the users access to various commands through a
  115. privilege mechanism.  Default privileges are assigned in the routine
  116. getcfg and defined in slugnet.h.  These may be over-ridden by a pri or a
  117. net entry in the slugnet configuration file for slugnet and slugnetd
  118. respectively. The privileges are described by a single letter and are as
  119. follows:
  120. .PP
  121. a : administrative commands.
  122. .PP
  123. b : broadcast allowed.
  124. .PP
  125. d : redirection allowed.
  126. .PP
  127. f : file access allowed.
  128. .PP
  129. j : join command allowed.
  130. .PP
  131. n : set name command allowed.
  132. .PP
  133. p : private messages allowed.
  134. .PP
  135. r : ring command allowed.
  136. .PP
  137. s : shell access allowed.
  138. .LP
  139. Of these, d, f, and s are affected by the setuid problem.
  140. .PP
  141. The number of users slugnet can support is limited only by the number of
  142. processes on your system.  Each user executes his/her own copy of the
  143. program.
  144.  
  145. .B "Configuring slugnet"
  146. .LP
  147. Slugnet reads a configuration file in the slugnet directory
  148. named "slugsys.dat".  This file contains lines of the following format:
  149.  
  150. .ce 1
  151. keyword=value
  152. .LP
  153. The valid keywords and options follow:
  154. .LP
  155. .B acc
  156. Access mode (default "immediate").  In slugnet's sorted past,
  157. it once had its own login
  158. routine.  Access was granted to new users based on the value of this
  159. keyword.  The acceptable values were "immediate",
  160. "delayed", and "denied."
  161. .LP
  162. .B act
  163. Accounting file name (default "slugact.dat").  The file in the slugnet
  164. directory that contains
  165. accounting records.
  166. .LP
  167. .B bgn
  168. Prelogin file name (default "slugbgn.dat"). This once served as slugnet's
  169. prelogin file.  Since
  170. the login routines were removed, it's not much different than news.
  171. .LP
  172. .B bil
  173. Billing mode (default "off").  Obsolete.
  174. Acceptable values are "on" or "off".
  175. .LP
  176. .B blf
  177. Billing file name (default "slugbil.dat"). Obsolete. Where user billing
  178. information was kept.
  179. .LP
  180. .B def
  181. Definition file name (default "slugdef.dat"), user or system.
  182. If you run slugnet on System V
  183. with user file privileges, this is the default name of the user
  184. definition file (where users define their own commands).  For slugnetd,
  185. and slugnet on BSD-based systems, it is a file for system-wide
  186. definitions.
  187. .LP
  188. .B  dir
  189. Directory file name (default "slugdir.dat").  Obsolete.  Where user
  190. registration information was kept.
  191. .LP
  192. .B hlp
  193. Help file name (default "slughlp.dat").  The help file.  New topics may
  194. be added, but not after the line that begins with the string "*EOF:".
  195. Each topic should be indicated by a line containing an asterisk, the
  196. topic name in upper case, and a trailing colon.
  197. .LP
  198. .B jsn
  199. Jsn file name (default "slugjsn.dat").  The jsn  is part of the unique
  200. identifier assigned to every slugnet user (the host name is the
  201. remaining part).
  202. .LP
  203. .B log
  204. Use login mode (default "off" ).  Obsolete.
  205. Acceptable values are "on" or "off".
  206. .LP
  207. .B mod
  208. Modem initialization string (default "ATZ S0=1 X1 E0 V0 S2=128").  Very
  209. obsolete.
  210. .LP
  211. .B new
  212. News file name (default "slugnew.dat"). A file that is displayed after
  213. the user connects (in early versions, after the user logged in).
  214. .LP
  215. .B net
  216. Permission set for slugnetd (default PRIVS).  See above for details.
  217. .LP
  218. .B por
  219. Communications port. Obsolete.
  220. .LP
  221. .B pri
  222. Permission set for slugnet (default PRIVS).  See above for details.
  223. .LP
  224. .B pro
  225. User/system prologue file (default "slugpro.dat").  Commands to be
  226. executed once user has connected to slugnet.
  227. .LP
  228. .B  usr
  229. User file name (default "slugusr.dat").  This is the table of
  230. currently active users.
  231. .LP
  232. .B val
  233. Validation file (default "slugval.dat").  Obsolete.  Where login
  234. information was kept.
  235. .PP
  236. You might wish to create a definition file to make things easier for
  237. users who might be used to other conferencing systems.  Here is a copy
  238. of mine:
  239.  
  240. .br
  241. *
  242. .br
  243. * for IRC users
  244. .br
  245. *
  246. .br
  247. /bye=exit;
  248. .br
  249. /expert=set novice off;
  250. .br
  251. /irc=set continuous on;
  252. .br
  253. /join=join;
  254. .br
  255. /names=show confer;
  256. .br
  257. /nick=set name;
  258. .br
  259. /quit=quit;
  260. .br
  261. /who *=show members;
  262. .br
  263. /who=show confer;
  264. .br
  265. *
  266. .br
  267. * abbreviations
  268. .br
  269. *
  270. .br
  271. se conf=set configuration;
  272. .br
  273. se cont=set continuous;
  274. .br
  275. se def=set definition;
  276. .br
  277. se del=set delay;
  278. .br
  279. se echop=set echoplex;
  280. .br
  281. se e=set echo;
  282. .br
  283. se l=set login;
  284. .br
  285. se na=set name;
  286. .br
  287. se no=set novice;
  288. .br
  289. se prol=set prolog;
  290. .br
  291. se prom=set prompt;
  292. .br
  293. se r=set ring;
  294. .br
  295. se t=set timer;
  296. .br
  297. se w=set wait;
  298. .br
  299. sh b=show buffer;
  300. .br
  301. sh confe=show confer;
  302. .br
  303. sh confi=show configuration;
  304. .br
  305. sh h=show hosts;
  306. .br
  307. sh l=show logins;
  308. .br
  309. sh m=show members;
  310. .br
  311. sh m=show members;
  312.  
  313. .B "Administrative commands"
  314. .LP
  315. Currently, slugnet has only one administrative command, "show all",
  316. which shows all the users on all the conferences whether they are
  317. invisible or not.  The earliest versions had another command, which began
  318. with a "$" and contained a target jsn and command.  When executed, it
  319. forced the target jsn to execute the command (this is, in fact how the
  320. ring command works, by forcing the target jsn to execute the bell
  321. command).  Since the owner of slugnet (but not slugnetd) has access to
  322. the shell, and owns all slugnet and slugnetd process, I removed the
  323. second command as unnecessary.  If you need to kill a user, use "show
  324. all" to get his/her pid, and use the shell escape and the Unix kill
  325. command to send it a signal - I recommend "kill -1".
  326. .PP
  327. Slugnet needs very little in the way of maintenance.  The accounting
  328. file should be flushed at regular intervals and the status of the
  329. network server ought to be checked once in a while.  I also try to
  330. collect any error messages slugnetd may issue.
  331. .PP
  332. I've changed my rc.local to start up slugnetd on reboot by adding the
  333. following line:
  334.  
  335. echo 'rm slugusr.dat; /usr/local/bin/slugnetd &' | su - slugnet >/dev/null
  336.  
  337. .B "Access Control"
  338. .LP
  339. Neither slugnet or slugnetd provide access control.  If you desire to
  340. add your own access control, I suggest that it be added into slugnet.c.
  341. The easiest thing to do might be to use some of the obsolete keywords in
  342. getcfg.c (like val) to point to a validation file and use a grep to see
  343. if a particular host or user was validated.  When creating a validation
  344. mechanism, it is important to note that for remote users, only the
  345. host name can be validated (you might want to see how the "set login"
  346. command attempts to validate remote users).
  347.  
  348. .B "Suggestions for modifications"
  349.  
  350. .LP
  351. 1. A slugnet-specific client would be very nice, as it would solve all
  352. setuid-related problems.  
  353. .LP
  354. 2. I worked a bit on a distributed-server model (not quite entirely
  355. unlike IRC) but abandoned it when it became clear to me that the server
  356. would have to be changed in a way that I felt was unfriendly to remote
  357. users.  My hacks are set off by the def SERVER.  If you compile slugnetd
  358. with SERVER, you'd better have some sort of access control.
  359. .LP
  360. 3. I suppose that conference and server operators might be nice, but I
  361. think they are more trouble than they are worth. If you need to control
  362. your users that much, you probably shouldn't be running slugnet.
  363.  
  364. .B "Accounting file format"
  365. .LP
  366. All fields are separated by colons.
  367.  
  368. .br
  369. Field 1:    login@host
  370. .br
  371. Field 2:    jsn
  372. .br
  373. Field 3:    bytes input
  374. .br
  375. Field 4:    bytes output
  376. .br
  377. Field 5:    login time in seconds from 1970
  378. .br
  379. Field 6:    logout time in seconds from 1970
  380. .br
  381. Field 7:    connect time in seconds
  382. .br
  383. Field 8:    day name, month, day, military time, and year.
  384.  
  385. \End\Of\Shar\
  386. else
  387.   echo "will not over write ./slugnet.doc"
  388. fi
  389. chmod 400 ./slugnet.doc
  390. if [ `wc -c ./slugnet.doc | awk '{printf $1}'` -ne 11723 ]
  391. then
  392. echo `wc -c ./slugnet.doc | awk '{print "Got " $1 ", Expected " 11723}'`
  393. fi
  394. if `test ! -s ./slugnet.h`
  395. then
  396. echo "writing ./slugnet.h"
  397. cat > ./slugnet.h << '\End\Of\Shar\'
  398. /* @(#)slugnet.h    1.13 */
  399. #include "copyright.h"
  400.  
  401. #include <stdio.h>
  402. #include <fcntl.h>
  403.  
  404. #ifdef SUNOS
  405. #define O_FSYNC O_SYNC
  406. #endif
  407.  
  408. #if defined( SYSV3 ) && !defined( UNICOS )
  409.  
  410. #include <filehdr.h>
  411. #include <scnhdr.h>
  412.  
  413. #endif 
  414.  
  415. #ifdef SYSV2
  416.  
  417. #include <filehdr.h>
  418. #include <scnhdr.h>
  419. #include <ldfcn.h>
  420.  
  421. #endif SYSV2
  422.  
  423. #include <unistd.h>
  424. #ifdef INTERLAN
  425. #include <interlan/il_types.h>
  426. #else
  427. #include <sys/types.h>
  428. #endif
  429. #include <sys/stat.h>
  430. #include <signal.h>
  431. #ifdef INTERLAN
  432. #define SIGCHLD SIGCLD
  433. #define SIGURG SIGUSR2
  434. #endif INTERLAN
  435.  
  436. #define ON 1
  437. #define OFF 0
  438. #define CRLF 1
  439. #define NOCRLF 0
  440.  
  441. #define BS 8
  442. #define CR 13
  443. #define DEL 127
  444. #define LF 10
  445.  
  446. #define CFRLEN 32
  447. #define FLNMLN 16
  448. #define JSNLEN 5
  449. #define LINLEN 80
  450.  
  451. #define NAMLEN 32
  452.  
  453. #define UNLEN  8
  454.  
  455. #define HOSTLEN 64
  456. #define PIDLEN 32
  457. #define MODELN 2
  458.  
  459. #define ADD 0
  460. #define ALLOW 1
  461. #define DELAY 2
  462. #define DENY -1
  463. #define RETRY -2
  464.  
  465. #define ADMIN 1
  466. #define DEBUG 0
  467. #define LOGIN 1
  468. #define MSGLEN 2048
  469. #define PRMLEN 34
  470.  
  471. #define DIRLEN 80
  472.  
  473. #define TIMEOUT 5
  474.  
  475. #define BLANKS " "
  476.  
  477. char *strcat(),*strcpy(),*strncpy(),*strchr(),*strrchr();
  478. #ifdef BSD4
  479. char *sprintf();
  480. #endif BSD4
  481.  
  482. int hungup;
  483. int stopscroll;
  484.  
  485. struct slugdir
  486. {
  487.     char name[ NAMLEN ];
  488.     char un[ UNLEN ];
  489.     char jsn[ JSNLEN ];
  490.     char confer[ CFRLEN ];
  491.     char rcvfil[ FLNMLN ];
  492.     char host[ HOSTLEN ];
  493.     char pid[ PIDLEN ];
  494.     char mode[ MODELN ];
  495. };
  496.  
  497. /* default privileges */
  498.  
  499. #ifdef SYSV2
  500. #ifndef NETWORK
  501. #define PRIVS        "_bfjnprs"
  502. #else
  503. #define PRIVS        "_bjnpr"
  504. #endif
  505. #endif SYSV2
  506. #ifdef SYSV3
  507. #ifndef NETWORK
  508. #define PRIVS        "_bfjnprs"
  509. #else
  510. #define PRIVS        "_bjnpr"
  511. #endif
  512. #endif SYSV3
  513. #ifdef BSD4
  514. #ifndef NETWORK
  515. #define PRIVS        "_bjnpr"
  516. #else
  517. #define PRIVS        "_bjnpr"
  518. #endif
  519. #endif BSD4
  520. #ifdef ULTRIX
  521. #ifndef NETWORK
  522. #define PRIVS        "_bjnpr"
  523. #else
  524. #define PRIVS        "_bjnpr"
  525. #endif
  526. #endif ULTRIX
  527.  
  528. \End\Of\Shar\
  529. else
  530.   echo "will not over write ./slugnet.h"
  531. fi
  532. chmod 400 ./slugnet.h
  533. if [ `wc -c ./slugnet.h | awk '{printf $1}'` -ne 1864 ]
  534. then
  535. echo `wc -c ./slugnet.h | awk '{print "Got " $1 ", Expected " 1864}'`
  536. fi
  537. if `test ! -s ./slugnet.mk`
  538. then
  539. echo "writing ./slugnet.mk"
  540. cat > ./slugnet.mk << '\End\Of\Shar\'
  541. #
  542. # @(#)slugnet.mk    1.7: makefile for $(SLUGNET)
  543. #
  544. # Empty macros are set by calling makefile
  545. #
  546. SLUGBIN =
  547. SLUGDIR =
  548. SLUGUID =
  549. OS =
  550. SLUGNET =
  551. MAN =
  552. NETFLG =
  553. #
  554. SLGFLG = -DSLUGDIR=\"$(SLUGDIR)\"
  555. CFLAGS = $(OS) $(SLGFLG) $(NETFLG)
  556. #
  557. DATA = slughlp.dat
  558.  
  559. DOCS = Readme slugnet.1 slugnetd.1 slugnet.doc slugnet.n
  560.  
  561. HEADERS = copyright.h net.h slugnet.h
  562.  
  563. MAKES = Makefile slugnet.mk
  564.  
  565. OBJECTS = call_socket.o callbyaddr.o callbyhost.o chgusr.o cleanup.o\
  566.         clnusr.o establish.o find.o get_connect.o getcfg.o getjsn.o lock.o\
  567.         lower.o main.o rdline.o receive.o repchar.o send_file.o setjsn.o\
  568.         sighang.o sigquit.o sigstop.o sigterm.o sigtstp.o sigurg.o slugnet.o\
  569.         strnicmp.o task.o transmit.o unlock.o verify.o
  570.  
  571. SOURCES = call_socket.c callbyaddr.c callbyhost.c chgusr.c cleanup.c\
  572.         clnusr.c establish.c find.c get_connect.c getcfg.c getjsn.c lock.c\
  573.         lower.c main.c rdline.c receive.c repchar.c send_file.c setjsn.c\
  574.         sighang.c sigquit.c sigstop.c sigterm.c sigtstp.c sigurg.c slugnet.c\
  575.         strnicmp.c task.c transmit.c unlock.c verify.c
  576.  
  577. $(SLUGNET): $(OBJECTS)
  578.     cc $(OBJECTS) $(LDFLAGS) -o $(SLUGNET)
  579. #
  580. # routines
  581. #
  582. call_socket.o: net.h call_socket.c
  583.  
  584. callbyaddr.o: net.h callbyaddr.c
  585.  
  586. callbyhost.o: net.h callbyhost.c
  587.  
  588. cleanup.o: net.h cleanup.c
  589.  
  590. chgusr.o: slugnet.h chgusr.c
  591.  
  592. establish.o: net.h establish.c
  593.  
  594. find.o: slugnet.h find.c
  595.  
  596. get_connect.o: net.h get_connect.c
  597.  
  598. getcfg.o: slugnet.h getcfg.c
  599.  
  600. getjsn.o: slugnet.h getjsn.c
  601.  
  602. lock.o: slugnet.h lock.c
  603.  
  604. lower.o: slugnet.h lower.c
  605.  
  606. main.o: net.h main.c
  607.  
  608. slugnet.o: slugnet.h slugnet.c
  609.  
  610. rdline.o: slugnet.h rdline.c
  611.  
  612. receive.o: slugnet.h receive.c
  613.  
  614. repchar.o: slugnet.h repchar.c
  615.  
  616. send_file.o: slugnet.h send_file.c
  617.  
  618. setjsn.o: slugnet.h setjsn.c
  619.  
  620. sighang.o: slugnet.h sighang.c
  621.  
  622. sigquit.o: slugnet.h sigquit.c
  623.  
  624. sigstop.o: slugnet.h sigstop.c
  625.  
  626. sigterm.o: slugnet.h sigterm.c
  627.  
  628. sigtstp.o: slugnet.h sigtstp.c
  629.  
  630. sigurg.o: slugnet.h sigurg.c
  631.  
  632. strnicmp.o: slugnet.h strnicmp.c
  633.  
  634. task.o: net.h task.c
  635.  
  636. transmit.o: slugnet.h transmit.c
  637.  
  638. unlock.o: slugnet.h unlock.c
  639.  
  640. verify.o: net.h verify.c
  641.  
  642. clean:
  643.     @echo "Removing objects..."
  644.     @rm -f $(OBJECTS)
  645.  
  646. install: $(SLUGDIR) $(SLUGBIN)
  647.     @echo "Installing $(SLUGNET)..."
  648.     cp $(SLUGNET) $(SLUGBIN)/$(SLUGNET)
  649.     chown $(SLUGUID) $(SLUGBIN)/$(SLUGNET)
  650.     @size $(SLUGBIN)/$(SLUGNET)
  651.     chmod u+s $(SLUGBIN)/$(SLUGNET)
  652.     chmod oug+x $(SLUGBIN)/$(SLUGNET)
  653.     cp slughlp.dat $(SLUGDIR)/slughlp.dat
  654.     chmod og-w $(SLUGDIR)/slughlp.dat
  655.     chmod u+w $(SLUGDIR)/slughlp.dat
  656.     chmod uog+r $(SLUGDIR)/slughlp.dat
  657.     chown $(SLUGUID) $(SLUGDIR)/*
  658.     @echo "Installing man page for $(SLUGNET)..."
  659.     cp $(SLUGNET).1 $(MAN)/$(SLUGNET).1
  660.     chmod og-w $(MAN)/$(SLUGNET).1
  661.     chmod u+w $(MAN)/$(SLUGNET).1
  662.     chmod uog+r $(MAN)/$(SLUGNET).1
  663. #
  664. # if slugnet is NOT setuid $(SLUGUID), following statement should be
  665. # uncommented.
  666. #
  667. #    chmod oug+rw $(SLUGDIR)
  668. $(SLUGBIN):
  669.     mkdir $(SLUGBIN)
  670. $(SLUGDIR):
  671.     mkdir $(SLUGDIR)
  672. #
  673. # tar
  674. #
  675. slugtar: $(DATA) $(DOCS) $(HEADERS) $(MAKES) $(SOURCES)
  676.     tar -cvf slugtar $(DATA) $(DOCS) $(HEADERS) $(MAKES) $(SOURCES)
  677. \End\Of\Shar\
  678. else
  679.   echo "will not over write ./slugnet.mk"
  680. fi
  681. chmod 400 ./slugnet.mk
  682. if [ `wc -c ./slugnet.mk | awk '{printf $1}'` -ne 3035 ]
  683. then
  684. echo `wc -c ./slugnet.mk | awk '{print "Got " $1 ", Expected " 3035}'`
  685. fi
  686. echo "Finished archive 3 of 6"
  687. exit
  688.