home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / mood / part01 next >
Text File  |  1993-04-09  |  104KB  |  3,850 lines

  1. Newsgroups: comp.sources.unix
  2. From: quanstro@stolaf.edu (goon)
  3. Subject: v26i118: mood - social programs including rwhod, rwho replacements, Part01/01
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: quanstro@stolaf.edu (goon)
  8. Posting-Number: Volume 26, Issue 118
  9. Archive-Name: mood/part01
  10.  
  11. Mood 0.92a --- a collection of "social" programs. 
  12.  
  13.      This was compiled on a SPARC running SunOS 4.1.2, VAX running
  14.      XINU Unix, and a NeXT running NeXTOS 2.1. I make no claims about
  15.      portability of these programs to other systems. If you have a bug
  16.      fix please mail me at quanstro@stolaf.edu. I will endevour to
  17.      answer all questions promptly but can make no promises that all
  18.      bugs will actually be fixed. (How I wish I could!)
  19.  
  20.      * what is a mood? A mood is whatever one want's it to be. For
  21.      example, on my system, these were the moods on 2. Feb 1992:
  22.      [moberg  ]  Jennie is feeling that life is wonderful.
  23.      [knobel  ]  Laura is butt sore from her 2nd big
  24.                  bike ride of the season . . . Oh where are all
  25.                  those wonderful backrubs when you need them???
  26.                  Curse interim break!  *sigh*
  27.      [...]
  28.  
  29.      * fmood: gets other user's moods and displays them in various and
  30.      sundry formats. (there is a shell script which is installed by
  31.      make install which can be useful if fmood is not compiled for a
  32.      particular architecture)
  33.  
  34.      * daemon: this is the daemon for doing remote moods. Mood is
  35.      perfectly happy attempting to connect to a remote mood server
  36.      with the constructs "mood dek@foo.bar.com" or "mood
  37.      dek@131.21.3.1". 
  38.  
  39.      * ffriends: prints out the log in names of your "friends" (the
  40.      people whose login names appear in ~/.friends. (There is also a
  41.      slower shell-script version which provides more information but
  42.      this verbose output is harder to manipulate and to format to
  43.      one's own liking)
  44.  
  45.      * theirmail: reports on the status of other user's mailboxes.
  46.  
  47.      * geeks: reports on the ten geekiest people on the system (by
  48.      number of hours logged in)
  49.  
  50.      * in.rwhod: the daemon for my implementation of rwho. This
  51.      implemenation is minimally 2n! faster than Berkeley rwho and is
  52.      noticablly faster than finger (1) even on a SPARC II. 
  53.  
  54.      When run with the command like `-c <server>' then in.rwhod does
  55.      the client thing, reporting when necessary back to the server.
  56.      When run without these options, in.rwhod does the server thing
  57.      collecting information from clients and responding to queries. 
  58.  
  59.      * rwho: the user-level interface to the in.rwhod server.
  60.      typical output looks like
  61.      [mari.acc.stolaf]  quanstro ttyp3    (loki4.cs.stolaf.)
  62.      [mari.acc.stolaf]  quanstro ttyp4    (loki4.cs.stolaf.)
  63.      [mari.acc.stolaf]  tremlh   ttyp5    (g-atalk2.atalk.s)
  64.      [mari.acc.stolaf]  matgress ttyp6    (xyplex1.stolaf.e)
  65.      [mari.acc.stolaf]  fritchie ttyp8    (spare2.acc.stola)
  66.      [asgaard.acc.sto]  gruetzne ttyp0    (131.234.128.231 )
  67.      [asgaard.acc.sto]  tremlh   ttyp1    (g-atalk2.atalk.s)
  68.  
  69.      * rw: a reformatter for rwho output. Typical output looks like
  70.      [mari.acc.stolaf] schultej quanstro quanstro quanstro quanstro
  71.                        tremlh matgress fritchie
  72.      [asgaard.acc.sto] gruetzne tremlh math12c fritchie
  73.      [newton.acc.stol] quanstro
  74.  
  75. Have fun and happy hacking!
  76.  
  77.     quanstro@stolaf.edu (goon, ewq)
  78.  
  79. #! /bin/sh
  80. # This is a shell archive.  Remove anything before this line, then unpack
  81. # it by saving it into a file and typing "sh file".  To overwrite existing
  82. # files, type "sh file -c".  You can also feed this as standard input via
  83. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  84. # will see the following message at the end:
  85. #        "End of archive 1 (of 1)."
  86. # Contents:  ChangeLog MANIFEST Makefile README TODO UNSHAR.HDR
  87. #   daemon.8 daemon.c ffriends.1 ffriends.c fmood.1 fmood.c friends.1
  88. #   friends.5 friends.d geeks.1 geeks.d hist in.rwhod.8 in.rwhod.c
  89. #   mitime.d mood.1 mood.d moodmail.1 moodmail.d rfriends.d rw.1 rw.d
  90. #   rwho.1 rwho.c theirmail.1 theirmail.d
  91. # Wrapped by vixie@gw.home.vix.com on Sat Apr 10 00:55:12 1993
  92. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  93. if test -f 'ChangeLog' -a "${1}" != "-c" ; then 
  94.   echo shar: Will not clobber existing file \"'ChangeLog'\"
  95. else
  96. echo shar: Extracting \"'ChangeLog'\" \(328 characters\)
  97. sed "s/^X//" >'ChangeLog' <<'END_OF_FILE'
  98. Thu May 21 20:27:34 1992  Erik Quanstrom  (quanstro at newton.acc.stolaf.edu)
  99. X
  100. X    * in.rwhod: fixed a fencepost error in the client. Did some more
  101. X    code housecleaning.
  102. X
  103. Wed Apr 29 16:34:17 1992  Erik Quanstrom  (quanstro at asgaard.acc.stolaf.edu)
  104. X
  105. X    * in.rwhod: fixed race the client_wait function. Did some
  106. X    code-housecleaning.
  107. X
  108. END_OF_FILE
  109. if test 328 -ne `wc -c <'ChangeLog'`; then
  110.     echo shar: \"'ChangeLog'\" unpacked with wrong size!
  111. fi
  112. # end of 'ChangeLog'
  113. fi
  114. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  115.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  116. else
  117. echo shar: Extracting \"'MANIFEST'\" \(1106 characters\)
  118. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  119. X   File Name        Archive #    Description
  120. X-----------------------------------------------------------
  121. X ChangeLog                  1    
  122. X MANIFEST                   1    This shipping list
  123. X Makefile                   1    
  124. X README                     1    
  125. X TODO                       1    
  126. X UNSHAR.HDR                 1    
  127. X daemon.8                   1    
  128. X daemon.c                   1    
  129. X ffriends.1                 1    
  130. X ffriends.c                 1    
  131. X fmood.1                    1    
  132. X fmood.c                    1    
  133. X friends.1                  1    
  134. X friends.5                  1    
  135. X friends.d                  1    
  136. X geeks.1                    1    
  137. X geeks.d                    1    
  138. X hist                       1    
  139. X in.rwhod.8                 1    
  140. X in.rwhod.c                 1    
  141. X mitime.d                   1    
  142. X mood.1                     1    
  143. X mood.d                     1    
  144. X moodmail.1                 1    
  145. X moodmail.d                 1    
  146. X rfriends.d                 1    
  147. X rw.1                       1    
  148. X rw.d                       1    
  149. X rwho.1                     1    
  150. X rwho.c                     1    
  151. X theirmail.1                1    
  152. X theirmail.d                1    
  153. END_OF_FILE
  154. if test 1106 -ne `wc -c <'MANIFEST'`; then
  155.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  156. fi
  157. # end of 'MANIFEST'
  158. fi
  159. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  160.   echo shar: Will not clobber existing file \"'Makefile'\"
  161. else
  162. echo shar: Extracting \"'Makefile'\" \(5199 characters\)
  163. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  164. X#########################################################################
  165. X# file:        Makefile for the mood program suite            #
  166. X#                                    #
  167. X# Object:    be social                        #
  168. X#                                     #
  169. X# Version:    .50                            #
  170. X#                                    #
  171. X# Erik Quanstrom                            #
  172. X# 9. Januar 1992                            #
  173. X#########################################################################
  174. X# here is where you start modifying the makefile
  175. X
  176. X# this should be the "root" of the project. This directory normally
  177. X# contains the subdirs bin, man and lib. But where the files end up is 
  178. X# determined by following paramaters.
  179. X#ROOT        =    /usr/local
  180. ROOT        =    /home/accserv1/stub/e/quanstro
  181. X
  182. X# ROOT_SH is just an escaped version of $(ROOT). These _must_ be the 
  183. X# same and because of the quoting wierdness of the shell, double
  184. X# slashes are required.
  185. X#ROOT_SH          =    \\/usr\\/local
  186. ROOT_SH         =    \\/home\\/accserv1\\/stub\\/e\\/quanstro
  187. X
  188. X# this is the directory where the binaries go.
  189. X#BIN_DIR    =    $(ROOT)/bin
  190. X#BIN_DIR     =    $(ROOT)/SPARCbin
  191. X#BIN_DIR     =    $(ROOT)/SUN3bin
  192. X#BIN_DIR      =    $(ROOT)/NeXTbin
  193. BIN_DIR      =    $(ROOT)/VAXbin
  194. X
  195. X# this is the directory where the executable shell scripts go.
  196. BIN_SH_DIR    =    $(ROOT)/bin
  197. X
  198. X# this is where the man files go. We are expecting to have at least
  199. X# the subdirectories man1 man5 and man8. 
  200. MAN_DIR        =    $(ROOT)/man
  201. X
  202. X# this is the file which daemon exec's to find the mood of a user
  203. X# when querried by a remote host. Other possibilities are mood, but 
  204. X# this will be slower
  205. X#EXEC_FILE    =    "\"$(ROOT)/bin/fmood\""
  206. X#EXEC_FILE    =    "\"$(ROOT)/SPARCbin/fmood\""
  207. X#EXEC_FILE    =    "\"$(ROOT)/SUN3bin/fmood\""
  208. X#EXEC_FILE    =    "\"$(ROOT)/NeXTbin/fmood\""
  209. XEXEC_FILE    =    "\"$(ROOT)/VAXbin/fmood\""
  210. X
  211. X# This is the default rwho server. I suggest that a NIS alias be set
  212. X# up so that the local server can be referenced by the name
  213. X# "rwhoserv." Sometimes it is convienient to specify the full domain
  214. X# as well. Numbers are generally a bad idea because you really don't
  215. X# want to recompile this thing if you change ip numbers. (This seems
  216. X# like a bug to me, but probablly won't get fixed right away)
  217. X#DEFAULT_SERV    =    "\"rwhoserv.stolaf.edu\""
  218. DEFAULT_SERV    =    "\"mari.acc.stolaf.edu\""
  219. X
  220. X# set the parms for the shell files
  221. X
  222. X# this is where the mail on your system resides
  223. MAIL_DIR    =    \\/usr\\/spool\\/mail
  224. X
  225. X# this is where the list of "mooders<" for moodmail resides
  226. MOODERS        =    $(ROOT_SH)\\/lib\\/mooders
  227. X
  228. X# and this is the path for shell scripts. I have the SPARCbin in
  229. X# there, because I work in a hetrogenious environment. This means that
  230. X# I am faced with several sets of executables. If this program is
  231. X# going to be intstalled in /usr/local/bin or some other standars
  232. X# place, there is nothing to worry about, but if not, then it would be
  233. X# wise to edit this to perhaps read `/bin/arch` instead of $h.
  234. X# ($h := $(ROOT))
  235. PATH        =    $h/SPARCbin:/bin:/usr/bin:/usr/ucb:/usr/local/bin
  236. SH_PATH        =     \\$$h\\/SPARCbin:\/bin:\\/usr\\/bin:\\/usr\\/ucb:\\/usr\\/local\\/bin
  237. X
  238. X# finally: what CC are you using? It must be ANSII, because I make 
  239. X# heavy use of prototypes, etc. I did all my work with GCC.
  240. X#CC        =    gcc -g        # debug
  241. CC        =    gcc -O4        # install
  242. X
  243. X# okay --- you can run make now
  244. X
  245. SH_SOURCE    =    geeks.d mood.d friends.d moodmail.d\
  246. X            theirmail.d rw.d rfriends.d
  247. SH_EXEC        =    geeks mood friends moodmail theirmail rw rfriends
  248. C_SOURCE    =    daemon.c ffriends.c fmood.c in.rwhod.c rwho.c
  249. MAN1_SOURCE    =    ffriends.1 fmood.1 friends.1 geeks.1 mood.1\
  250. X            moodmail.1 theirmail.1 rw.1 rwho.1 
  251. MAN5_SOURCE    =    friends.5
  252. MAN8_SOURCE    =    daemon.8 in.rwhod.8
  253. PROGRAM        =    daemon ffriends fmood in.rwhod rwho
  254. X
  255. X.SUFFIXES: .d $(.SUFFIXES)
  256. X
  257. ALL: $(PROGRAM) $(SH_EXEC)
  258. X
  259. daemon: daemon.c
  260. X    $(CC) -DMOOD=$(EXEC_FILE) -o daemon daemon.c
  261. X
  262. fmood:  fmood.c
  263. X    $(CC) -o fmood fmood.c
  264. X
  265. rwho:    rwho.c
  266. X    $(CC) -DSERVER=$(DEFAULT_SERV) -o rwho rwho.c
  267. X
  268. ffriends: ffriends.c
  269. X    $(CC) -o ffriends ffriends.c
  270. X
  271. in.rwhod: in.rwhod.c
  272. X    $(CC) -o in.rwhod in.rwhod.c
  273. X
  274. rfriends friends geeks mood rw: rfriends.d friends.d geeks.d mood.d rw.d
  275. X    @echo editing $@
  276. X    @cp $@.d $@
  277. X    @(echo '/^h=' ; echo 's/=.*/='$(ROOT_SH)'/';\
  278. X      echo '/^PATH=' ; echo 's/=.*/='$(SH_PATH)'/';\
  279. X      echo 'w' ; echo 'q') | ed $@ > /dev/null 2>&1
  280. X    @chmod a+x $@
  281. X
  282. theirmail: theirmail.d
  283. X    @echo editing $@
  284. X    @cp $@.d $@
  285. X    @(echo '/^h=' ; echo 's/=.*/='$(MAIL_DIR)'/';\
  286. X      echo '/^PATH=' ; echo 's/=.*/='$(SH_PATH)'/';\
  287. X      echo 'w' ; echo 'q') | ed $@ > /dev/null 2>&1
  288. X    @chmod a+x $@
  289. X
  290. moodmail: moodmail.d
  291. X    @echo editing $@
  292. X    @cp $@.d $@
  293. X    @(echo '/^h=' ; echo 's/=.*/='$(ROOT_SH)'/'; echo '/^mfile=';\
  294. X      echo 's/=.*/='$(MOODERS)'/';\
  295. X      echo '/^PATH=' ; echo 's/=.*/='$(SH_PATH)'/';\
  296. X      echo 'w' ; echo 'q') | ed $@ > /dev/null 2>&1
  297. X    @chmod a+x $@;
  298. X
  299. X####
  300. clean::
  301. X    rm -f $(O_SOURCE) $(PROGRAM) $(SH_EXEC)
  302. X
  303. spotless: clean
  304. X    rm -f $(C_SOURCE:.c=.c~) $(MAN1_SOURCE:.1=.1~)$(MAN5_SOURCE:.5=.5~)\
  305. X          $(MAN8_SOURCE:.8=.8~)
  306. X
  307. install: ALL install_man install_sh
  308. X    -strip $(PROGRAM) ;\
  309. X       install -g staff -m 755 -o root $(PROGRAM) $(BIN_DIR)
  310. X
  311. install_sh:
  312. X    -install -g staff -m 755 -o root $(SH_EXEC) $(BIN_SH_DIR)
  313. X#    -ln -s $(BIN_SH_DIR)/friends $(BIN_SH_DIR)/rfriends
  314. X    
  315. install_man:
  316. X    -install -g staff -m 644 -o root $(MAN5_SOURCE) $(MAN_DIR)/man5
  317. X    -install -g staff -m 644 -o root $(MAN1_SOURCE) $(MAN_DIR)/man1
  318. X    -install -g staff -m 644 -o root $(MAN8_SOURCE) $(MAN_DIR)/man8
  319. END_OF_FILE
  320. if test 5199 -ne `wc -c <'Makefile'`; then
  321.     echo shar: \"'Makefile'\" unpacked with wrong size!
  322. fi
  323. # end of 'Makefile'
  324. fi
  325. if test -f 'README' -a "${1}" != "-c" ; then 
  326.   echo shar: Will not clobber existing file \"'README'\"
  327. else
  328. echo shar: Extracting \"'README'\" \(3994 characters\)
  329. sed "s/^X//" >'README' <<'END_OF_FILE'
  330. Mood 0.90 --- a collection of "social" programs. 
  331. X
  332. X     This was compiled on a SPARC running SunOS 4.1.2, VAX running
  333. X     XINU Unix, and a NeXT running NeXTOS 2.1. I make no claims about
  334. X     portability of these programs to other systems. If you have a bug
  335. X     fix please mail me at quanstro@stolaf.edu. I will endevour to
  336. X     answer all questions promptly but can make no promises that all
  337. X     bugs will actually be fixed. (How I wish I could!)
  338. X
  339. X     * what is a mood? A mood is whatever one want's it to be. For
  340. X     example, on my system, these were the moods on 2. Feb 1992:
  341. X     [moberg  ]  Jennie is feeling that life is wonderful.
  342. X     [knobel  ]  Laura is butt sore from her 2nd big
  343. X                 bike ride of the season . . . Oh where are all
  344. X                 those wonderful backrubs when you need them???
  345. X                 Curse interim break!  *sigh*
  346. X     [percival]  Daniel is feeling it.  Yes, again.
  347. X     [moore   ]  Michael is feeling lethargic.  Two days, 9 things.
  348. X     [millerjl]  Jeffrey is feeling that lonliness, since it is
  349. X                 everlasting, is actually the god which rules the
  350. X                 universe.
  351. X     [quanstro]  goon is feeling like ralphing, again.
  352. X     [avelsgaa]  Sarah is feeling very hungry.  I think I will go
  353. X                 bite Jeffery's big toe.
  354. X     [knappenp]  Paul is feeling like the Magical Mister
  355. X                 Mistoffiles.
  356. X     [alannarm]  Alanna is feeling ...hmmm how do you i feel, pretty
  357. X                 good, almost confident, and definitely kinky...
  358. X                 the question is: is this a good thing???
  359. X                 enstappy?
  360. X     [jeff    ]  Jeff is feeling happy.  I feel happy.  I feel ...
  361. X                 *bonk*
  362. X     [andersow]  W is feeling like break is ending too soon........
  363. X
  364. X     * fmood: gets other user's moods and displays them in various and
  365. X     sundry formats. (there is a shell script which is installed by
  366. X     make install which can be useful if fmood is not compiled for a
  367. X     particular architecture)
  368. X
  369. X     * daemon: this is the daemon for doing remote moods. Mood is
  370. X     perfectly happy attempting to connect to a remote mood server
  371. X     with the constructs "mood dek@foo.bar.com" or "mood
  372. X     dek@131.21.3.1". 
  373. X
  374. X     * ffriends: prints out the log in names of your "friends" (the
  375. X     people whose login names appear in ~/.friends. (There is also a
  376. X     slower shell-script version which provides more information but
  377. X     this verbose output is harder to manipulate and to format to
  378. X     one's own liking)
  379. X
  380. X     * theirmail: reports on the status of other user's mailboxes.
  381. X
  382. X     * geeks: reports on the ten geekiest people on the system (by
  383. X     number of hours logged in)
  384. X
  385. X     * in.rwhod: the daemon for my implementation of rwho. This
  386. X     implemenation is minimally 2n! faster than Berkeley rwho and is
  387. X     noticablly faster than finger (1) even on a SPARC II. 
  388. X
  389. X     When run with the command like `-c <server>' then in.rwhod does
  390. X     the client thing, reporting when necessary back to the server.
  391. X     When run without these options, in.rwhod does the server thing
  392. X     collecting information from clients and responding to queries. 
  393. X     
  394. X     * rwho: the user-level interface to the in.rwhod server.
  395. X     typical output looks like
  396. X     [mari.acc.stolaf]  quanstro ttyp3    (loki4.cs.stolaf.)
  397. X     [mari.acc.stolaf]  quanstro ttyp4    (loki4.cs.stolaf.)
  398. X     [mari.acc.stolaf]  tremlh   ttyp5    (g-atalk2.atalk.s)
  399. X     [mari.acc.stolaf]  matgress ttyp6    (xyplex1.stolaf.e)
  400. X     [mari.acc.stolaf]  fritchie ttyp8    (spare2.acc.stola)
  401. X     [asgaard.acc.sto]  gruetzne ttyp0    (131.234.128.231 )
  402. X     [asgaard.acc.sto]  tremlh   ttyp1    (g-atalk2.atalk.s)
  403. X    
  404. X     * rw: a reformatter for rwho output. Typical output looks like
  405. X     [mari.acc.stolaf] schultej quanstro quanstro quanstro quanstro
  406. X                       tremlh matgress fritchie
  407. X     [asgaard.acc.sto] gruetzne tremlh math12c fritchie
  408. X     [newton.acc.stol] quanstro
  409. X
  410. Have fun and happy hacking!
  411. X
  412. ewq
  413. END_OF_FILE
  414. if test 3994 -ne `wc -c <'README'`; then
  415.     echo shar: \"'README'\" unpacked with wrong size!
  416. fi
  417. # end of 'README'
  418. fi
  419. if test -f 'TODO' -a "${1}" != "-c" ; then 
  420.   echo shar: Will not clobber existing file \"'TODO'\"
  421. else
  422. echo shar: Extracting \"'TODO'\" \(1123 characters\)
  423. sed "s/^X//" >'TODO' <<'END_OF_FILE'
  424. X-*- indented-text -*-
  425. X
  426. fmood:     * control characters are passwd through. This is not a
  427. X     feature! In fact, this can really munge up terminals, etc.
  428. X
  429. X     * fix formatting. Here several things need to be done. First
  430. X     double spacing (on account of newlines) should not happen.
  431. X     Second, tabs, should act more like tabs. Thirdly, newlines
  432. X     should act like newlines. 
  433. X
  434. X     * should the moods be stored in a centeral repository? this
  435. X     would make lookups FAST. How should this work? Perhaps
  436. X     moodmail -a  could cache them? This would be an easy scheme
  437. X     to implement.
  438. X
  439. in.rwhod * how should this program handle domains? There are several
  440. X     options here, and it's not really clear which is the best.
  441. X     A single server could handle multiple domains, doing
  442. X     on-the-fly lookup. 
  443. X
  444. rwho:     * server lookup: can this be done in a portable way? 
  445. X
  446. rw,
  447. friends: * this is a problem because of the path settings. The
  448. X     wrong executable will come across the path first if you are
  449. X     on the wrong archetecture. :( This is rather a pain in the
  450. X     butt. I could have an arch environment variable, I think that
  451. X     is the ticket. (for _me_, at least)
  452. END_OF_FILE
  453. if test 1123 -ne `wc -c <'TODO'`; then
  454.     echo shar: \"'TODO'\" unpacked with wrong size!
  455. fi
  456. # end of 'TODO'
  457. fi
  458. if test -f 'UNSHAR.HDR' -a "${1}" != "-c" ; then 
  459.   echo shar: Will not clobber existing file \"'UNSHAR.HDR'\"
  460. else
  461. echo shar: Extracting \"'UNSHAR.HDR'\" \(4918 characters\)
  462. sed "s/^X//" >'UNSHAR.HDR' <<'END_OF_FILE'
  463. Return-Path: news@stolaf.edu
  464. Received: by cognition.pa.dec.com; id AA19501; Tue, 26 May 92 12:52:19 -0700
  465. Received: by inet-gw-2.pa.dec.com; id AA21734; Tue, 26 May 92 12:50:03 -0700
  466. Received: from relay1.UU.NET by rodan.UU.NET with SMTP (5.61/UUNET-mail-drop) id AA08927; Tue, 26 May 92 15:49:42 -0400
  467. Received: from stolaf.edu (via nic.stolaf.edu) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA00390; Tue, 26 May 92 15:49:07 -0400
  468. Received: from news.stolaf.edu by stolaf.edu (4.1/SMI-4.1)id AA13766; Tue, 26 May 92 14:48:23 CDT
  469. Newsgroups: comp.sources.unix
  470. Path: news.stolaf.edu!quanstro
  471. XFrom: quanstro@stolaf.edu (goon)
  472. Subject: mood-0.92a (includes complete rwho replacement)
  473. Message-Id: <QUANSTRO.92May26144742@asgaard.StOlaf.edu>
  474. Sender: news@stolaf.edu
  475. Organization: St. Olaf College, Northfield, MN USA
  476. Distribution: comp
  477. Date: 26 May 92 14:47:42
  478. Apparently-To: <comp-sources-unix@uunet.uu.net>
  479. X
  480. Mood 0.92a --- a collection of "social" programs. 
  481. X
  482. X     This was compiled on a SPARC running SunOS 4.1.2, VAX running
  483. X     XINU Unix, and a NeXT running NeXTOS 2.1. I make no claims about
  484. X     portability of these programs to other systems. If you have a bug
  485. X     fix please mail me at quanstro@stolaf.edu. I will endevour to
  486. X     answer all questions promptly but can make no promises that all
  487. X     bugs will actually be fixed. (How I wish I could!)
  488. X
  489. X     * what is a mood? A mood is whatever one want's it to be. For
  490. X     example, on my system, these were the moods on 2. Feb 1992:
  491. X     [moberg  ]  Jennie is feeling that life is wonderful.
  492. X     [knobel  ]  Laura is butt sore from her 2nd big
  493. X                 bike ride of the season . . . Oh where are all
  494. X                 those wonderful backrubs when you need them???
  495. X                 Curse interim break!  *sigh*
  496. X     [percival]  Daniel is feeling it.  Yes, again.
  497. X     [moore   ]  Michael is feeling lethargic.  Two days, 9 things.
  498. X     [millerjl]  Jeffrey is feeling that lonliness, since it is
  499. X                 everlasting, is actually the god which rules the
  500. X                 universe.
  501. X     [quanstro]  goon is feeling like ralphing, again.
  502. X     [avelsgaa]  Sarah is feeling very hungry.  I think I will go
  503. X                 bite Jeffery's big toe.
  504. X     [knappenp]  Paul is feeling like the Magical Mister
  505. X                 Mistoffiles.
  506. X     [alannarm]  Alanna is feeling ...hmmm how do you i feel, pretty
  507. X                 good, almost confident, and definitely kinky...
  508. X                 the question is: is this a good thing???
  509. X                 enstappy?
  510. X     [jeff    ]  Jeff is feeling happy.  I feel happy.  I feel ...
  511. X                 *bonk*
  512. X     [andersow]  W is feeling like break is ending too soon........
  513. X
  514. X     * fmood: gets other user's moods and displays them in various and
  515. X     sundry formats. (there is a shell script which is installed by
  516. X     make install which can be useful if fmood is not compiled for a
  517. X     particular architecture)
  518. X
  519. X     * daemon: this is the daemon for doing remote moods. Mood is
  520. X     perfectly happy attempting to connect to a remote mood server
  521. X     with the constructs "mood dek@foo.bar.com" or "mood
  522. X     dek@131.21.3.1". 
  523. X
  524. X     * ffriends: prints out the log in names of your "friends" (the
  525. X     people whose login names appear in ~/.friends. (There is also a
  526. X     slower shell-script version which provides more information but
  527. X     this verbose output is harder to manipulate and to format to
  528. X     one's own liking)
  529. X
  530. X     * theirmail: reports on the status of other user's mailboxes.
  531. X
  532. X     * geeks: reports on the ten geekiest people on the system (by
  533. X     number of hours logged in)
  534. X
  535. X     * in.rwhod: the daemon for my implementation of rwho. This
  536. X     implemenation is minimally 2n! faster than Berkeley rwho and is
  537. X     noticablly faster than finger (1) even on a SPARC II. 
  538. X
  539. X     When run with the command like `-c <server>' then in.rwhod does
  540. X     the client thing, reporting when necessary back to the server.
  541. X     When run without these options, in.rwhod does the server thing
  542. X     collecting information from clients and responding to queries. 
  543. X     
  544. X     * rwho: the user-level interface to the in.rwhod server.
  545. X     typical output looks like
  546. X     [mari.acc.stolaf]  quanstro ttyp3    (loki4.cs.stolaf.)
  547. X     [mari.acc.stolaf]  quanstro ttyp4    (loki4.cs.stolaf.)
  548. X     [mari.acc.stolaf]  tremlh   ttyp5    (g-atalk2.atalk.s)
  549. X     [mari.acc.stolaf]  matgress ttyp6    (xyplex1.stolaf.e)
  550. X     [mari.acc.stolaf]  fritchie ttyp8    (spare2.acc.stola)
  551. X     [asgaard.acc.sto]  gruetzne ttyp0    (131.234.128.231 )
  552. X     [asgaard.acc.sto]  tremlh   ttyp1    (g-atalk2.atalk.s)
  553. X    
  554. X     * rw: a reformatter for rwho output. Typical output looks like
  555. X     [mari.acc.stolaf] schultej quanstro quanstro quanstro quanstro
  556. X                       tremlh matgress fritchie
  557. X     [asgaard.acc.sto] gruetzne tremlh math12c fritchie
  558. X     [newton.acc.stol] quanstro
  559. X
  560. Have fun and happy hacking!
  561. X
  562. ewq
  563. X
  564. END_OF_FILE
  565. if test 4918 -ne `wc -c <'UNSHAR.HDR'`; then
  566.     echo shar: \"'UNSHAR.HDR'\" unpacked with wrong size!
  567. fi
  568. # end of 'UNSHAR.HDR'
  569. fi
  570. if test -f 'daemon.8' -a "${1}" != "-c" ; then 
  571.   echo shar: Will not clobber existing file \"'daemon.8'\"
  572. else
  573. echo shar: Extracting \"'daemon.8'\" \(1197 characters\)
  574. sed "s/^X//" >'daemon.8' <<'END_OF_FILE'
  575. X.TH daemon 8 "14. January 1992"
  576. X.SH NAME
  577. daemon 0.90 \- the daemon for 
  578. X.BR mood (1)
  579. remote moods.
  580. X.SH SYNOPSIS
  581. daemon [\-p 
  582. X.IR port ] 
  583. X[[\-e] 
  584. X.IR exec_file ]
  585. X.SH DESCRIPTION
  586. X.B Daemon
  587. lurks in the background, waiting for a connection on a port, which
  588. defaults to 9302 (this is an utterly random number) or be specified on
  589. the command line via the \-p option. When 
  590. X.B daemon 
  591. receives a connection, then it sends all the input from the socket
  592. to 
  593. X.I exec_file,
  594. which defaults to /usr/local/bin/fmood. The standard output and
  595. standard input from 
  596. X.I exec_file
  597. are send over the socket back to the calling process. 
  598. X.SH BUGS
  599. X.B Daemon
  600. seems to be bug free. (Knock on wood!)
  601. X.SH "SEE ALSO"
  602. X.BR friends (1),
  603. X.BR friends (5),
  604. X.BR moodmail (1),
  605. X.BR mood (1),
  606. X.BR fmood (1),
  607. X.SH AUTHOR
  608. Copyright (C) 1991, 1992 by Erik Quanstrom
  609. X
  610. Permission to use, copy, modify, and distribute this software and its
  611. documentation for any purpose and without fee is hereby granted, provided
  612. that the above copyright notice appear in all copies and that both that
  613. copyright notice and this permission notice appear in supporting
  614. documentation.  This software is provided ``as is'' without express or
  615. implied warranty.
  616. X
  617. END_OF_FILE
  618. if test 1197 -ne `wc -c <'daemon.8'`; then
  619.     echo shar: \"'daemon.8'\" unpacked with wrong size!
  620. fi
  621. # end of 'daemon.8'
  622. fi
  623. if test -f 'daemon.c' -a "${1}" != "-c" ; then 
  624.   echo shar: Will not clobber existing file \"'daemon.c'\"
  625. else
  626. echo shar: Extracting \"'daemon.c'\" \(7144 characters\)
  627. sed "s/^X//" >'daemon.c' <<'END_OF_FILE'
  628. X/************************************************************************
  629. X * file:    daemon.c                        *
  630. X *                                     *
  631. X * Object:    provied a mood daemon                    *
  632. X *                                     *
  633. X *                                    *
  634. X *                                    *
  635. X * Copyright (C) Erik Quanstrom, 1992                    *
  636. X * Under the terms expressed in the manual page                *
  637. X *                                    *
  638. X * Erik Quanstrom                            *
  639. X * 14. Januar 1992                            *
  640. X ************************************************************************/
  641. X#define DEFAULT_PORT     9302
  642. X#ifndef MOOD
  643. X#define MOOD        "/usr/local/bin/fmood"
  644. X#endif
  645. X#define BSIZE         1024 * 8
  646. X#define SPECIAL        '*'
  647. X#define FLAG        '-'
  648. X
  649. X#include <stdio.h>
  650. X#include <sys/types.h>
  651. X#include <sys/file.h>
  652. X#include <sys/socket.h>
  653. X#include <netdb.h>
  654. X#include <netinet/in.h>
  655. X
  656. typedef struct sockaddr SOCK;
  657. typedef struct sockaddr_in SOCK_IN;
  658. X
  659. char **Envp;    /* pass on the same environment */
  660. char *host;    /* only figure out what the host name is once */
  661. char *program;
  662. char *path = NULL;
  663. X
  664. int open_socket(int port);
  665. void process_connection(int s);
  666. int wait_for_connection(int s);
  667. void die(int c);
  668. void warn(void);
  669. char *strdup(char *s);
  670. X
  671. X/************************************************************************
  672. X * function:    main()                            *
  673. X *                                     *
  674. X * object:     provide an rmood server                    *
  675. X *                                     *
  676. X * Erik Quanstrom                            *
  677. X * 2. Oktober 1991                            *
  678. X ************************************************************************/
  679. int main ( int argc, char **argv, char **envp) 
  680. X{
  681. X  int s;
  682. X  int port = DEFAULT_PORT;
  683. X
  684. X  program = *argv;
  685. X
  686. X  host = (char *)malloc(100 * sizeof (char));
  687. X  gethostname (host, 100);
  688. X  
  689. X  while (++argv && *argv)
  690. X    {
  691. X      if (**argv == FLAG)
  692. X    {
  693. X      if (!*(argv + 1))
  694. X        usage();
  695. X
  696. X      switch (*(*argv + 1))
  697. X        {
  698. X        case 'p': /* port */
  699. X          argv++;
  700. X          port = atoi(*argv);
  701. X          break;
  702. X        case 'r': /* run */
  703. X          if (path)
  704. X        usage();
  705. X
  706. X          path = *argv;
  707. X          break;
  708. X        default:
  709. X          usage();
  710. X          /* NOT_REACHED */
  711. X        }
  712. X    }
  713. X      else
  714. X    path = *argv;
  715. X    }
  716. X
  717. X  if (!path)
  718. X    path = MOOD;
  719. X  
  720. X  s = open_socket( port );
  721. X
  722. X  Envp = envp;
  723. X  
  724. X  do
  725. X    process_connection(wait_for_connection(s));
  726. X  while (1);
  727. X
  728. X  close(s);
  729. X
  730. X  return 0;
  731. X}
  732. X
  733. X/************************************************************************
  734. X * function:    usage()                            *
  735. X *                                     *
  736. X * object:     print out the usage message                *
  737. X *                                     *
  738. X * Erik Quanstrom                            *
  739. X * 14. Jaunar 1992                            *
  740. X ************************************************************************/
  741. int usage(void)
  742. X{
  743. X  fprintf(stderr, "usage: %s [-p port] [[-r] program]\n", program);
  744. X  exit(1);
  745. X}
  746. X
  747. X/************************************************************************
  748. X * function:    wait_for_connection()                    *
  749. X *                                     *
  750. X * object:     sit and wait for a connection                *
  751. X *                                     *
  752. X * Erik Quanstrom                            *
  753. X * 2. Oktober 1991                            *
  754. X ************************************************************************/
  755. int wait_for_connection(int s)
  756. X{
  757. X  int new,
  758. X      newlen = sizeof(SOCK_IN);
  759. X  
  760. X  SOCK_IN *new_socket = (SOCK_IN *)malloc(sizeof(SOCK_IN));
  761. X  
  762. X  if ((new = accept(s, new_socket, &newlen)) < 0)
  763. X    die(-4);
  764. X  
  765. X  return new;
  766. X}
  767. X
  768. X/************************************************************************
  769. X * function:    process_connection()                    *
  770. X *                                     *
  771. X * object:     return the requested information across the socket    *
  772. X *                                     *
  773. X * Erik Quanstrom                            *
  774. X * 2. Oktober 1991                            *
  775. X ************************************************************************/
  776. void process_connection(int s)
  777. X{
  778. X  int child;
  779. X  
  780. X  switch (fork())
  781. X    {
  782. X    case 0:
  783. X      break;
  784. X    case -1:
  785. X      warn();
  786. X      break;
  787. X    default:
  788. X      {
  789. X    int n;
  790. X    int argv_size = 100;
  791. X    int csize = 0;
  792. X    
  793. X    FILE *f;
  794. X      
  795. X    char **argv = (char **)malloc(argv_size * sizeof(char *));
  796. X    char **argv_base = argv;
  797. X    char *p;
  798. X    
  799. X    *argv_base = strdup( path );
  800. X    argv++;
  801. X
  802. X    f = fdopen(s, "r");
  803. X      
  804. X    while ((n = getc(f)) != EOF)
  805. X      {
  806. X        if (n == SPECIAL)
  807. X          break;
  808. X        
  809. X        if (n == ' ' || n == '\t' || n == '\n')
  810. X          {
  811. X        if ((argv - argv_base) >= argv_size)
  812. X          {
  813. X            int diff = argv - argv_base;
  814. X            
  815. X            argv_size += 100;
  816. X            argv_base = (char **)realloc((void *)argv_base, argv_size);
  817. X            argv = argv_base + diff;
  818. X            
  819. X            csize = 0;
  820. X          }
  821. X
  822. X        argv++;
  823. X        *argv = NULL;
  824. X          }
  825. X        else
  826. X          {
  827. X        if (!*argv)
  828. X          {
  829. X            csize = 50;
  830. X            p = *argv = (char *)malloc(sizeof(char) * csize);
  831. X          }
  832. X        else if ((p - *argv) > csize)
  833. X          {
  834. X            int diff = p - *argv;
  835. X            csize += 50;
  836. X            
  837. X            *argv = (char *)realloc((void *)*argv, csize);
  838. X            
  839. X            p = *argv + diff;
  840. X          }
  841. X          
  842. X        *p = n;
  843. X        p++;
  844. X          
  845. X          }
  846. X      }
  847. X      
  848. X    if (*argv)
  849. X      ++argv, *argv = NULL; /* terminate the vector */
  850. X
  851. X    fflush(f);
  852. X    close(f);
  853. X
  854. X    write(s, "[", 1);
  855. X    write(s, host, strlen(host));
  856. X    write(s, "]\n", 2);
  857. X
  858. X    dup2(s, 1); /* stdout is socket */
  859. X    dup2(s, 2); /* stderr is socket */
  860. X
  861. X    execve( path, argv_base, Envp);
  862. X    /* NOT REACHED */
  863. X      }
  864. X    }
  865. X  
  866. X  wait(NULL);
  867. X  close(s);
  868. X}  
  869. X
  870. X/************************************************************************
  871. X * function:    open_socket()                        *
  872. X *                                     *
  873. X * object:     open a internet domain socket for connections        *
  874. X *                                     *
  875. X * Erik Quanstrom                            *
  876. X * 2. Oktober 1991                            *
  877. X ************************************************************************/
  878. int open_socket(int port)
  879. X{
  880. X  int s;
  881. X  SOCK_IN *sin = (SOCK_IN *)malloc(sizeof(SOCK_IN));
  882. X
  883. X  if ( (s = socket(PF_INET,SOCK_STREAM, 0)) == -1 )
  884. X    die(-1);
  885. X
  886. X  sin->sin_addr.s_addr = INADDR_ANY;
  887. X  sin->sin_family = AF_INET;
  888. X  sin->sin_port = htons( port );
  889. X
  890. X  if (bind(s, sin, sizeof(SOCK_IN)) < 0)
  891. X    die(-2);
  892. X
  893. X
  894. X  if (listen(s, 5))
  895. X    die(-3);
  896. X  
  897. X  return s;
  898. X}  
  899. X
  900. void die(int c)
  901. X{
  902. X  perror(program);
  903. X  exit(c);
  904. X}
  905. X
  906. X/************************************************************************
  907. X * funciton:    warn();                                                 *
  908. X *                                                                      *
  909. X * object:      print warning messages on failed system calls        *
  910. X *                                                                      *
  911. X * Erik Quanstrom                                                       *
  912. X * 25. Januar 1992                                                      *
  913. X ************************************************************************/
  914. void warn(void)
  915. X{
  916. X  long t = time(NULL);
  917. X  static char s[20];
  918. X  
  919. X  perror((char *)sprintf(s, "%15.15s ", (char *)(ctime(&t) + 4)));
  920. X}
  921. X
  922. X/************************************************************************
  923. X * funciton:    strdup();                                               *
  924. X *                                                                      *
  925. X * object:      malloc and copy a string                                *
  926. X *                                                                      *
  927. X * Erik Quanstrom                                                       *
  928. X * 20. Juli 1991                                                        *
  929. X ************************************************************************/
  930. char *strdup(char *foo)
  931. X{
  932. X  char *tmp = (char *)malloc(sizeof(char) * strlen(foo) ),
  933. X       *p = tmp;
  934. X
  935. X  /* make sure to copy the NULL */
  936. X  do
  937. X    *tmp++ = *foo;
  938. X  while ( *foo++ );
  939. X
  940. X  return p;
  941. X}
  942. END_OF_FILE
  943. if test 7144 -ne `wc -c <'daemon.c'`; then
  944.     echo shar: \"'daemon.c'\" unpacked with wrong size!
  945. fi
  946. # end of 'daemon.c'
  947. fi
  948. if test -f 'ffriends.1' -a "${1}" != "-c" ; then 
  949.   echo shar: Will not clobber existing file \"'ffriends.1'\"
  950. else
  951. echo shar: Extracting \"'ffriends.1'\" \(1232 characters\)
  952. sed "s/^X//" >'ffriends.1' <<'END_OF_FILE'
  953. X.TH friends 1 " 2. December 1991"
  954. X.SH NAME
  955. ffriends 0.90 \- print out friends logged in.
  956. X
  957. X.SH SYNOPSIS
  958. ffriends [\-f 
  959. X.IR friends_file ]
  960. X
  961. X.SH DESCRIPTION
  962. X.B Ffriends
  963. displays the login name of each person listed in the ~/.friends file,
  964. one per line.
  965. The output of friends is intentionally terse as this sort of output
  966. is best suited for input into other programs.
  967. X
  968. X.SH OPTIONS
  969. These are the current (supported) options:
  970. X.TP 10
  971. X\fB\-f file 
  972. use 
  973. X.I file 
  974. instead of ~/.friends.
  975. X
  976. X.SH BUGS
  977. None have surfaced yet.
  978. X
  979. X.SH "SEE ALSO"
  980. X.BR mood (1)
  981. X.BR fmood (1)
  982. X.BR moodmail (1)
  983. X.BR friends (1)
  984. X.BR friends (5)
  985. X
  986. X.SH FILES
  987. X.PD 0
  988. X.TP 20
  989. X.B ~/.friends
  990. friends file
  991. X.TP
  992. X.B /etc/utmp
  993. who is logged in
  994. X.TP
  995. X.B /etc/passwd
  996. for users' names
  997. X.TP
  998. X.B /var/adm/lastlog
  999. last login times
  1000. X.TP
  1001. X.B /etc/ttytab
  1002. terminal locations
  1003. X.PD
  1004. X.SH AUTHOR
  1005. Copyright (C) 1991, 1992 by Erik Quanstrom
  1006. X
  1007. Permission to use, copy, modify, and distribute this software and its
  1008. documentation for any purpose and without fee is hereby granted, provided
  1009. that the above copyright notice appear in all copies and that both that
  1010. copyright notice and this permission notice appear in supporting
  1011. documentation.  This software is provided ``as is'' without express or
  1012. implied warranty.
  1013. END_OF_FILE
  1014. if test 1232 -ne `wc -c <'ffriends.1'`; then
  1015.     echo shar: \"'ffriends.1'\" unpacked with wrong size!
  1016. fi
  1017. # end of 'ffriends.1'
  1018. fi
  1019. if test -f 'ffriends.c' -a "${1}" != "-c" ; then 
  1020.   echo shar: Will not clobber existing file \"'ffriends.c'\"
  1021. else
  1022. echo shar: Extracting \"'ffriends.c'\" \(2828 characters\)
  1023. sed "s/^X//" >'ffriends.c' <<'END_OF_FILE'
  1024. X/************************************************************************
  1025. X * file:    ffriends.c                        *
  1026. X *                                     *
  1027. X * object:    print out all friends names on the system        *
  1028. X *                                     *
  1029. X * Copyright (C) Erik Quanstrom, 1992                    *
  1030. X * Under the terms expressed in the manual page                *
  1031. X *                                     *
  1032. X * Erik Quanstrom                            *
  1033. X * 8. Jan 1992                                *
  1034. X ************************************************************************/
  1035. X#include <stdio.h>
  1036. X#include <sys/types.h>
  1037. X#include <time.h>
  1038. X
  1039. X#include <utmp.h>
  1040. X#include <lastlog.h>
  1041. X
  1042. X#define    FLAG    '-'
  1043. X#define UTMP    "/etc/utmp"
  1044. X
  1045. typedef struct utmp Utmp;
  1046. X
  1047. void usage(char *name);
  1048. int find_friends(FILE *f, FILE *u);
  1049. X
  1050. X#ifndef nonuser
  1051. X#define nonuser(ut) ((ut).ut_host[0] == 0 && \
  1052. X    strncmp((ut).ut_line, "tty", 3) == 0 && ((ut).ut_line[3] == 'p' \
  1053. X                          || (ut).ut_line[3] == 'q' \
  1054. X                          || (ut).ut_line[3] == 'r' \
  1055. X                          || (ut).ut_line[3] == 's'))
  1056. X
  1057. X#endif /* !nonuser */
  1058. X
  1059. int main(int argc, char **argv, char **envp) 
  1060. X{
  1061. X  FILE *f = NULL;
  1062. X  FILE *u;
  1063. X  
  1064. X  char *program = *argv;
  1065. X  
  1066. X  /* parse arguments */
  1067. X  while (*++argv)
  1068. X    {
  1069. X      if (**argv == FLAG)
  1070. X    switch (*(*argv + 1))
  1071. X      {
  1072. X      case 'f':
  1073. X        argv++;
  1074. X        if (!*argv)
  1075. X          usage(program);
  1076. X        
  1077. X        if (!(f = fopen(*argv, "r")))
  1078. X          {
  1079. X        perror(program);
  1080. X        exit(1);
  1081. X          }
  1082. X        break;
  1083. X      default:
  1084. X        usage(program);
  1085. X        /* NOT_REACHED */;
  1086. X      }
  1087. X      else
  1088. X    usage(argv[0]);
  1089. X    }
  1090. X
  1091. X  /* open ~/.friends */
  1092. X  if (!f)
  1093. X    if (!(f = fopen((char *)strcat(getenv("HOME"), "/.friends"), "r")))
  1094. X      {
  1095. X    fprintf(stderr, "%s: $HOME/.friends not found.\n", program);
  1096. X    exit (1);
  1097. X      }
  1098. X  
  1099. X  /* try to open /usr/etc/utmp */
  1100. X
  1101. X  if (!(u = fopen(UTMP, "r")))
  1102. X    {
  1103. X      perror(argv[0]);
  1104. X      exit(1);
  1105. X    }
  1106. X
  1107. X  return find_friends(f,u);
  1108. X}
  1109. X
  1110. int find_friends(FILE *f, FILE *u)
  1111. X{
  1112. X  Utmp utmp_entry;
  1113. X  int size = 100;
  1114. X  char **friend = (char **)malloc(sizeof(char *) * size);
  1115. X  char **friendp = friend;
  1116. X
  1117. X  /* initilize the array */
  1118. X
  1119. X  while (!feof(f))
  1120. X    {
  1121. X      if (friendp - friend > size)
  1122. X    {
  1123. X      int diff = friendp - friend;
  1124. X      
  1125. X      size+=100;
  1126. X      friend = (char **)realloc((void *)friend, size * sizeof(char *));
  1127. X      friendp = friend + diff;
  1128. X    }
  1129. X      
  1130. X      *friendp = (char *)malloc(16 * sizeof(char));
  1131. X      
  1132. X      fscanf(f,"%8s", *friendp);    /* this is a hack, but efficient */
  1133. X      
  1134. X      friendp++;
  1135. X    }
  1136. X      
  1137. X  *friendp = NULL;
  1138. X  
  1139. X  while (!feof(u))
  1140. X    {
  1141. X      fread(&utmp_entry, sizeof(Utmp), 1, u);
  1142. X      if ((!*utmp_entry.ut_name) || (nonuser(utmp_entry)))
  1143. X    continue;
  1144. X      
  1145. X
  1146. X      friendp = friend;
  1147. X      while (friendp && *friendp)
  1148. X    {
  1149. X      if (!strncmp(utmp_entry.ut_name, *friendp, 8))
  1150. X        {
  1151. X          fprintf(stdout, "%s\n", *friendp);
  1152. X          break;
  1153. X        }
  1154. X      friendp++;
  1155. X    }
  1156. X    }
  1157. X  return 0;
  1158. X}
  1159. X
  1160. void usage(char *name)
  1161. X{
  1162. X  fprintf(stderr, "usage: %s [-f <friends_file>]\n", name);
  1163. X  exit(1);
  1164. X  /* NOT_REACHED */
  1165. X}  
  1166. END_OF_FILE
  1167. if test 2828 -ne `wc -c <'ffriends.c'`; then
  1168.     echo shar: \"'ffriends.c'\" unpacked with wrong size!
  1169. fi
  1170. # end of 'ffriends.c'
  1171. fi
  1172. if test -f 'fmood.1' -a "${1}" != "-c" ; then 
  1173.   echo shar: Will not clobber existing file \"'fmood.1'\"
  1174. else
  1175. echo shar: Extracting \"'fmood.1'\" \(4790 characters\)
  1176. sed "s/^X//" >'fmood.1' <<'END_OF_FILE'
  1177. X.TH fmood 1 " 12. January 1991"
  1178. X.SH NAME
  1179. fmood 0.90 \- get a user's mood
  1180. X.SH SYNOPSIS
  1181. fmood [\-m] < 
  1182. X.I new_mood
  1183. X.LP
  1184. fmood [\-vfa[#]] [\-] [
  1185. X.IR user1 [\h'-0.5m'
  1186. X.IR @host1 ] 
  1187. X.IR user2 [\h'-0.5m'
  1188. X.IR @host2 ]
  1189. X  .\|.\|. ] 
  1190. X.SH DESCRIPTION
  1191. X.BR Fmood
  1192. prints out the ``mood'' of different users in various and sundry formats.
  1193. When run with no arguments, 
  1194. X.BR fmood
  1195. trys to use
  1196. X.BR getpass (3)
  1197. to read the users login name. If that fails, 
  1198. X.BR fmood 
  1199. exits with status 1. 
  1200. If 
  1201. X.BR fmood 
  1202. has arguments and the \-m flag has not been specified, then it will
  1203. try to find the ``mood'' of each user in the argument list, trying to
  1204. connect to a remote mood server if the host is specified. If a user is
  1205. not found using  
  1206. X.BR getpwnam (3)
  1207. then 
  1208. X.BR fmood
  1209. prints:
  1210. X.IP
  1211. X.BI "just who the heck is <" name "> anyway?
  1212. X.LP
  1213. on standard error.
  1214. If a user has no ~/.mood file or a user's ~/.mood file cannot be read,
  1215. then 
  1216. X.I fmood
  1217. prints:
  1218. X.IP
  1219. X.BI "<" name "> is a stoic dweeb."
  1220. X.LP
  1221. on standard error.
  1222. If the file is readable, then 
  1223. X.I fmood 
  1224. will output
  1225. X.IP
  1226. X.BI "<" firstname "> is feeling <" contents_of_moodfile">"
  1227. X.LP
  1228. X
  1229. X.SH OPTIONS
  1230. These are the current (supported) options:
  1231. X.TP 10
  1232. X\fB\-v 
  1233. changes the output format of 
  1234. X.I fmood 
  1235. to include the user name and suppresses ``stoic dweeb'' and ``unknown
  1236. user'' error messages.
  1237. X.TP 10
  1238. X\fB\-f
  1239. gets the ``moods'' of all the people in your friends file (see 
  1240. X.BR friends (1))
  1241. X.TP 10
  1242. X\fB\-e[#]
  1243. Sets the expire time for moods. If # is not set then all the moods will be
  1244. printed. Otherwise, all the moods less than # days old will be printed.
  1245. X.TP 10
  1246. X\fB\-m
  1247. sets your ``mood'' to whatever is read from the standard input. Note
  1248. that control characters are not ignored, but unlike previous versions of 
  1249. X.BR mood (1),
  1250. this version prints out the entire file. Formatting will not
  1251. necessarily be preserved.
  1252. X.TP 10
  1253. X\fB\-
  1254. forces
  1255. X.B fmood
  1256. to take user names from standard input. For each occurrence of `\-' in
  1257. the argument list, standard input is read until 
  1258. X.SM EOF.
  1259. X.SH HISTORY
  1260. Glenn Elliott (whose infamous reputation for horrendous coding style,
  1261. said to be a result of first coding in
  1262. BASIC
  1263. and then converting the results to C, is truly undeserved) wrote the first
  1264. and quite possibly the best version of 
  1265. X.BR mood
  1266. at St. Olaf College in the fall of 1986. Pete TerMaat wrote his version of 
  1267. X.BR mood
  1268. in 1987, his Junior year at St. Olaf in 
  1269. X.BR sh (1)
  1270. and added a few features. In 1987 the 
  1271. X.I moodmail (1) 
  1272. mailing list got started by Pete and was a huge success but in the Fall of
  1273. X1988, since Pete had graduated, Brett M. Rabe and Henry Pierce raced to get
  1274. moodmail up-and-running. Brett was given the source by Pete but it is not
  1275. clear if Henry had gotten the source from tape or written a new version of
  1276. X.B mood 
  1277. himself. Henry had obtained the user-of-the-day and word-of-the-day as well
  1278. as the moodmail scripts but did not have the actual moodmail program. Brett,
  1279. on the other hand, had the mood program but none of the other stuff. In the
  1280. end, Brett became the new moodmailman. When Brett left St. Olaf in January
  1281. of 1989, Jeff Marker became the new moodmailman although he though that his
  1282. position was temporarly and so he left the program and the sources in Brett's
  1283. account.
  1284. X.PP
  1285. During the 90-91 school year, Brett's account was removed, forcing Jeff to
  1286. rewrite the program yet again, this time adding support for 
  1287. X.BR rmood
  1288. and a Sunday edition of the mood mailing list. Also added to the 
  1289. X.BR moodmail (1)
  1290. mailing list were, at various times, quotes from the Bible and the 
  1291. Kama Sutra.
  1292. X
  1293. In the Fall of 1991, Erik Quanstrom rewrote the entire package from scratch,
  1294. deleting many of the old features and adding some of his own, most notably
  1295. direct support for 
  1296. X.IP
  1297. X.BI "mood user@host" 
  1298. X.LP
  1299. remote moods. Erik set up his own mailing list when Jeff's account was
  1300. suspended, not realizing that Jeff Miller was temporarly running moodmail. 
  1301. X.SH BUGS
  1302. X.BR Fmood
  1303. will not preserve formatting. To some extent this cannot be
  1304. avoided in line breaking, but
  1305. X.B fmood 
  1306. should to a better job with this.
  1307. X.PP
  1308. X.BR Fmood
  1309. will pass non-ascii characters as well as non-printing characters to the
  1310. standard output. 
  1311. X.BR Mail (1)
  1312. has lots of problems with this and this encourages people to do
  1313. terminal-specific things in there moods.
  1314. X.SH "SEE ALSO"
  1315. X.BR daemon (8).
  1316. X.BR friends (1),
  1317. X.BR friends (5),
  1318. X.BR mood (1),
  1319. X.BR moodmail (1),
  1320. X
  1321. X.SH FILES
  1322. X~/.mood ~/.friends
  1323. X.SH AUTHOR
  1324. Copyright (C) 1991, 1992 by Erik Quanstrom
  1325. X
  1326. Permission to use, copy, modify, and distribute this software and its
  1327. documentation for any purpose and without fee is hereby granted, provided
  1328. that the above copyright notice appear in all copies and that both that
  1329. copyright notice and this permission notice appear in supporting
  1330. documentation.  This software is provided ``as is'' without express or
  1331. implied warranty.
  1332. END_OF_FILE
  1333. if test 4790 -ne `wc -c <'fmood.1'`; then
  1334.     echo shar: \"'fmood.1'\" unpacked with wrong size!
  1335. fi
  1336. # end of 'fmood.1'
  1337. fi
  1338. if test -f 'fmood.c' -a "${1}" != "-c" ; then 
  1339.   echo shar: Will not clobber existing file \"'fmood.c'\"
  1340. else
  1341. echo shar: Extracting \"'fmood.c'\" \(12721 characters\)
  1342. sed "s/^X//" >'fmood.c' <<'END_OF_FILE'
  1343. X/************************************************************************
  1344. X * file:    fmood    (0.90.00)                    * 
  1345. X *                                     * 
  1346. X * object:    to users moods (quickly)                *
  1347. X *                                    *
  1348. X *         the ephisis here is on correctness and speed. No     *
  1349. X *         thoughts were given during development to portability.    *
  1350. X *         However the only routine which may not be portable is     *
  1351. X *         tty_width()                        *
  1352. X *                                     *
  1353. X * files:    ~user/.mood                        *
  1354. X *         "/.friends                        *
  1355. X *                                    *
  1356. X * Copyright (C) Erik Quanstrom, 1992                    *
  1357. X * Under the terms expressed in the manual page                *
  1358. X *                                     *
  1359. X * Erik Quanstrom                            *
  1360. X * 11. Jaunuar 1992                            *
  1361. X ************************************************************************/
  1362. X#include <stdio.h>
  1363. X#include <sys/types.h>
  1364. X#include <pwd.h>
  1365. X#include <sys/ioctl.h>
  1366. X#include <sys/stat.h>
  1367. X#include <sys/socket.h>
  1368. X#include <sys/time.h>
  1369. X#include <netdb.h>
  1370. X#include <netinet/in.h>
  1371. X#include <sys/errno.h>
  1372. X
  1373. X#include <ctype.h>
  1374. X#include <string.h>
  1375. X/*#include "string.h"*/
  1376. X
  1377. X#define FLAG '-'
  1378. X#define DEFAULT_PORT  9302
  1379. X#define SPECIAL "*"
  1380. X#define SEC_IN_DAY 3600l * 24l
  1381. X
  1382. X#ifndef S_IXOTH
  1383. X#define S_IROTH  0000004
  1384. X#define EXEC_ALL 0000111
  1385. X#else
  1386. X#define EXEC_ALL S_IXOTH | S_IXGRP | S_IXUSR
  1387. X#endif
  1388. X
  1389. extern char *getenv(char *key);
  1390. extern char *getlogin(void);
  1391. X
  1392. char *get_pty_login(void);
  1393. int mood(char *name);
  1394. int rmood(char *name);
  1395. int Mood(char *name);
  1396. void usage(void);
  1397. void format(char *s, int len);
  1398. int tty_width(void);
  1399. char **read_friends(char *file);
  1400. void die(int status);
  1401. void warn(void);
  1402. char *strdup(char *s);
  1403. char *concat(char *a, char *b);
  1404. X
  1405. typedef struct sockaddr SOCK;
  1406. typedef struct sockaddr_in SOCK_IN;
  1407. X
  1408. enum bool
  1409. X{
  1410. X  false,
  1411. X  true
  1412. X} boolean;
  1413. X
  1414. X/* flags */
  1415. int dashv = 0;
  1416. int dashe = -1;
  1417. long dashe_days;
  1418. X
  1419. long TimeNow;
  1420. char *program;
  1421. int WindowSize;
  1422. X
  1423. int main(int argc, char **argv)
  1424. X{
  1425. X  int status = 0,
  1426. X      seen = false;
  1427. X  
  1428. X  TimeNow = time(NULL);
  1429. X  program = *argv;
  1430. X  
  1431. X  WindowSize = tty_width();
  1432. X
  1433. X  while (++argv && *argv)
  1434. X    if (**argv == FLAG && !strchr(*argv, '@'))
  1435. X      if (*(*argv +1) == '\0')
  1436. X    {
  1437. X      seen++;
  1438. X      mood_stdin();
  1439. X    }
  1440. X      else
  1441. X    while (++*argv && **argv)
  1442. X      {
  1443. X        switch (**argv)
  1444. X          {
  1445. X          case 'a':
  1446. X        {
  1447. X          char *offset = *argv + 1;
  1448. X          
  1449. X          if (isdigit(*offset))
  1450. X            {
  1451. X              dashe = 0;
  1452. X              for ( ; isdigit(*offset); offset++)
  1453. X            {
  1454. X              dashe *= 10;
  1455. X              dashe += *offset - '0';
  1456. X            }
  1457. X          
  1458. X              dashe_days = (SEC_IN_DAY) * (long)dashe;
  1459. X          
  1460. X              *argv = offset - 1;
  1461. X            }
  1462. X        }
  1463. X        seen++;
  1464. X        mood_all(dashe);
  1465. X        break;
  1466. X          case 'm':
  1467. X        {
  1468. X          struct stat buf;
  1469. X          char *home = getenv("HOME");
  1470. X          char c;
  1471. X          FILE *moodfile;
  1472. X          
  1473. X          seen++;
  1474. X          
  1475. X          if (-1 == stat(home, &buf))die(1);
  1476. X          if (-1 == chmod(home, buf.st_mode | EXEC_ALL)) die(1);
  1477. X          if (-1 == chdir(home)) die(1);
  1478. X          if (!(moodfile = fopen(".mood", "w"))) die(1);
  1479. X        
  1480. X          while ((c = getc(stdin)) != EOF)
  1481. X            putc(c, moodfile);
  1482. X
  1483. X          close(moodfile);
  1484. X          break;
  1485. X        }
  1486. X          case 'v':
  1487. X        dashv++;
  1488. X        break;
  1489. X          case 'f':
  1490. X        {
  1491. X          char **friends;
  1492. X          
  1493. X          seen++;
  1494. X          
  1495. X          friends = read_friends(strcat(getenv("HOME"), "/.friends"));
  1496. X
  1497. X          if (!friends)
  1498. X            break;
  1499. X          
  1500. X          while (**friends)
  1501. X            {
  1502. X              mood(*friends);
  1503. X              ++friends;
  1504. X            }
  1505. X            }
  1506. X        break;
  1507. X          default:
  1508. X        usage();
  1509. X        /* NOT_REACHED */
  1510. X          }
  1511. X      }
  1512. X    else    
  1513. X      seen++, status = mood(*argv);
  1514. X
  1515. X  if (!seen)
  1516. X    {
  1517. X      char *tmp;
  1518. X      
  1519. X      if ((tmp = getlogin()) || (tmp = get_pty_login()))
  1520. X    seen++, mood(strdup(tmp));
  1521. X      else 
  1522. X    {
  1523. X      fprintf(stderr, "%s: getlogin() failed. Is this a tty?\n", program);
  1524. X      exit(1);
  1525. X    }
  1526. X    }
  1527. X  
  1528. X  return status;
  1529. X}
  1530. X
  1531. char *get_pty_login(void)
  1532. X{
  1533. X  struct passwd *p;
  1534. X  
  1535. X  if (!isatty(0) && !isatty(1))
  1536. X    return (char *)NULL;
  1537. X  
  1538. X  return getpwuid(getuid())->pw_name;
  1539. X}
  1540. X
  1541. int mood_stdin(void)
  1542. X{
  1543. X  int s;
  1544. X  char *name = (char *)malloc(266 * sizeof(char));
  1545. X  char *namep = name;
  1546. X      
  1547. X  while ((*namep = getc(stdin)) != EOF)
  1548. X    {
  1549. X      if (*namep == ' ' || *namep == '\t' || *namep == '\n')
  1550. X    if (namep - name)
  1551. X      {
  1552. X        *namep = '\0';
  1553. X        s += mood(strdup(name));
  1554. X        namep = name;
  1555. X        continue;
  1556. X      }
  1557. X      namep++;
  1558. X    }
  1559. X      
  1560. X  if (namep - name)
  1561. X    {
  1562. X      namep = '\0';
  1563. X      mood(name);
  1564. X      namep = name;
  1565. X    }
  1566. X
  1567. X  return s;
  1568. X}
  1569. X
  1570. void usage(void)
  1571. X{
  1572. X  fprintf(stderr, 
  1573. X    "usage %s [-m new_mood] [-fva] [-e[#]] user1[@host1] ...\n", 
  1574. X      program);
  1575. X  exit(1);
  1576. X}
  1577. X
  1578. int mood(char *name)
  1579. X{
  1580. X  if (strchr(name, '@'))
  1581. X    return rmood(name);
  1582. X  else 
  1583. X    return Mood(name);
  1584. X}
  1585. X
  1586. int rmood(char *name)
  1587. X{
  1588. X  char *host;
  1589. X  char *user = strdup(name);
  1590. X  char *userp = user;
  1591. X  static char buf[1024 * 8];
  1592. X  struct hostent *hp;
  1593. X  int  s, n;
  1594. X  SOCK_IN * sin = (SOCK_IN *)malloc(sizeof(SOCK_IN));
  1595. X  
  1596. X  while (*userp != '@')
  1597. X    userp++;
  1598. X
  1599. X  *userp = '\0';
  1600. X  userp++;
  1601. X  
  1602. X  host = strdup(userp);
  1603. X  
  1604. X  if ( (sin->sin_addr.s_addr = inet_addr( host )) != -1)
  1605. X    sin->sin_family = AF_INET;
  1606. X  else
  1607. X    if (hp = gethostbyname(host))
  1608. X      {
  1609. X        sin->sin_family = hp->h_addrtype;
  1610. X        bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
  1611. X      }
  1612. X    else
  1613. X      {
  1614. X        fprintf(stderr, "unknown host %s\n", host);
  1615. X        exit(1);
  1616. X      } 
  1617. X
  1618. X  sin->sin_port = htons( (int)DEFAULT_PORT );
  1619. X
  1620. X  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  1621. X    {
  1622. X      perror(program);
  1623. X      return 1;
  1624. X    }
  1625. X
  1626. X  if (connect(s, sin, sizeof(SOCK_IN)) < 0)
  1627. X    {
  1628. X      perror(program);
  1629. X      close (s);
  1630. X      return 1;
  1631. X    }
  1632. X
  1633. X  if ((write(s, user, strlen(user)) < 0) || (write(s, SPECIAL, 1) < 0))
  1634. X    {
  1635. X      perror(program);
  1636. X      close(s);
  1637. X      return 1;
  1638. X    }
  1639. X
  1640. X  while (n = read(s, buf, 8 * 1024))
  1641. X    fwrite(buf, n, sizeof(char), stdout);
  1642. X    
  1643. X  close(s);
  1644. X  
  1645. X  free((void *)user);
  1646. X  free((void *)host);
  1647. X  /* do not free hp --- static memory */
  1648. X
  1649. X  return 0;
  1650. X}
  1651. X
  1652. int Mood(char *name)
  1653. X{
  1654. X  struct passwd *g;
  1655. X  static struct stat *s = NULL;
  1656. X  static int bufalloc = 0;
  1657. X  static char *buf = NULL; 
  1658. X  char *path;
  1659. X  FILE *f;
  1660. X  long fsize;
  1661. X  extern int errno;
  1662. X  
  1663. X  if (!s)
  1664. X    s = (struct stat *)malloc(sizeof(struct stat));
  1665. X
  1666. X  if (!(g = getpwnam(name)))
  1667. X    {
  1668. X      if (!dashv)
  1669. X          fprintf(stderr, "just who the heck is %s anyway?\n", name);
  1670. X      return 2;
  1671. X    }
  1672. X
  1673. X  /* warn if that is is the thing to do */
  1674. X  if ((stat(path = concat(g->pw_dir, "/.mood"), s) < 0) && 
  1675. X      (errno != EACCES) && (errno != ENOENT))
  1676. X    {
  1677. X      warn();
  1678. X      return 1;
  1679. X    }
  1680. X  
  1681. X  /* Should we test for some cases of bad permissions? 
  1682. X     this could be useful for those users who tend to
  1683. X     make inexperienced mistakes like setting the permissions
  1684. X     wrong
  1685. X   */
  1686. X
  1687. X  if ( ((dashe > 0) && ((TimeNow - s->st_mtime - dashe_days) > 0)) ||
  1688. X      !s->st_size || /* <- is this one the Right Thing to do? */
  1689. X      !(f = fopen(concat(g->pw_dir, "/.mood"), "r"))) 
  1690. X    {
  1691. X      if (!dashv)
  1692. X    fprintf(stderr, "%s is a stoic dweeb\n", strtok(g->pw_gecos, " ,"));
  1693. X    
  1694. X      return 1;
  1695. X    }
  1696. X  
  1697. X  if ((fsize = s->st_size) > bufalloc)
  1698. X    {
  1699. X      if (fsize < 8 * 1024L)
  1700. X    bufalloc = 8 * 1024;
  1701. X      else
  1702. X    bufalloc = (int)fsize;
  1703. X
  1704. X      if (!buf && (!(buf = (char *)malloc(bufalloc))))
  1705. X    die(2);
  1706. X      else if (!(buf = (char *)realloc((void *)buf, bufalloc)))
  1707. X    die(2);
  1708. X    }
  1709. X  
  1710. X  fread(buf, (int)fsize, sizeof(char), f);
  1711. X  fclose(f);
  1712. X  
  1713. X  if (dashv)
  1714. X    {
  1715. X      char *s = (char *)malloc(14 * sizeof(char));
  1716. X      sprintf(s, "[%-8s]   ", g->pw_name);
  1717. X      format(s, 12);
  1718. X      free((void *)s);
  1719. X    }
  1720. X  format(g->pw_gecos, strcspn(g->pw_gecos, ", "));
  1721. X  
  1722. X  format(" is feeling ", 12);
  1723. X  format(buf, fsize);
  1724. X  format(NULL , 0); /* send end of line */
  1725. X  
  1726. X  return 0;
  1727. X}
  1728. X
  1729. void format(char *s, int len)
  1730. X{
  1731. X  static int pos = 0;
  1732. X  int p = pos;
  1733. X
  1734. X  char *spoint = s;
  1735. X  char *smin = s;
  1736. X  char *smax = s + len - 1;
  1737. X
  1738. X  /* line break */
  1739. X  if (!s && !len)
  1740. X    {
  1741. X      fwrite("\n",1,sizeof(char),stdout);
  1742. X      pos = 0;
  1743. X      return;
  1744. X    }
  1745. X
  1746. X  /* now do the word breaking */
  1747. X  while (spoint <= smax)
  1748. X    {
  1749. X      spoint = smin;
  1750. X      while ((p < WindowSize ) && (spoint <= smax))
  1751. X    {
  1752. X      if (*spoint == ' ' || *spoint == '\t' || *spoint == '\n')
  1753. X        {
  1754. X          fwrite(smin, spoint - smin, sizeof(char),stdout);
  1755. X          fwrite(" ",1,sizeof(char),stdout);
  1756. X          pos += spoint - smin + 1;
  1757. X          smin = spoint + 1;
  1758. X        }
  1759. X      spoint++;
  1760. X      p++;
  1761. X    }
  1762. X      
  1763. X      if ( p >= WindowSize)
  1764. X    {
  1765. X      /* word is bigger than the window */
  1766. X      if (((pos + spoint - smin) >= WindowSize) && (spoint - smin >20))
  1767. X        {
  1768. X          int d = WindowSize - pos - 1;
  1769. X
  1770. X          fwrite(smin, d, sizeof(char),stdout);
  1771. X          smin += d;
  1772. X          spoint = smin;
  1773. X        }
  1774. X
  1775. X      p = pos = 12;
  1776. X      fwrite("\n            ", 13, sizeof(char), stdout);
  1777. X    }
  1778. X    }
  1779. X
  1780. X  fwrite(smin, smax - smin + 1, sizeof(char),stdout);
  1781. X
  1782. X  pos += smax - smin + 1;
  1783. X}
  1784. X
  1785. int tty_width(void)
  1786. X{
  1787. X  struct winsize win;
  1788. X  int fd;
  1789. X
  1790. X  if ((fd = open("/dev/tty", 0)) == -1)
  1791. X    return 79;
  1792. X
  1793. X  ioctl(fd, TIOCGWINSZ, &win);
  1794. X
  1795. X  if (win.ws_col != 0)
  1796. X    return win.ws_col - 1;
  1797. X
  1798. X  return 79;
  1799. X}
  1800. X
  1801. char **read_friends(char *file)
  1802. X{
  1803. X  FILE *f = fopen(file, "r");
  1804. X  int size = 100;
  1805. X  char **friend;
  1806. X  char **friendp;
  1807. X  
  1808. X  if (!f)
  1809. X    return (char **)NULL;
  1810. X
  1811. X  friendp = friend = (char **)malloc(size * sizeof(char *));
  1812. X  
  1813. X  while (!feof(f))
  1814. X    {
  1815. X      if (friendp - friend > size)
  1816. X    {
  1817. X      int diff = friendp - friend;
  1818. X      
  1819. X      size+=100;
  1820. X      friend = (char **)realloc((void *)friend, size * sizeof(char *));
  1821. X      friendp = friend + diff;
  1822. X    }
  1823. X      
  1824. X      *friendp = (char *)malloc(16 * sizeof(char));
  1825. X      
  1826. X      fscanf(f,"%8s", *friendp);    /* this is a hack, but efficient */
  1827. X      
  1828. X      friendp++;
  1829. X    }
  1830. X      
  1831. X  *friendp = NULL;
  1832. X
  1833. X  fclose(f);
  1834. X  return friend;
  1835. X}
  1836. X
  1837. int mood_all(int days)
  1838. X{
  1839. X  struct passwd *g;
  1840. X  struct stat *status = (struct stat *)malloc(sizeof(struct stat));
  1841. X  char *file;
  1842. X
  1843. X  int arraysize = 1000;  
  1844. X  char **array = (char **)malloc(arraysize * sizeof(char *));
  1845. X  char **arrayp = array;
  1846. X  char **arraymax = arrayp + arraysize;
  1847. X  
  1848. X  if (days == -1)
  1849. X    dashe_days = (long)3 * (SEC_IN_DAY);
  1850. X  
  1851. X  for ( g = getpwent(); g ; g = getpwent())
  1852. X    {
  1853. X      file = concat(g->pw_dir, "/.mood");
  1854. X      
  1855. X      if (stat(file, status))
  1856. X    continue;
  1857. X      
  1858. X      if ((status->st_mode & S_IROTH) && 
  1859. X      (!dashe_days || ((TimeNow - status->st_mtime  - dashe_days) < 0)))
  1860. X    {
  1861. X      *arrayp = strdup(g->pw_name);
  1862. X      arrayp++;
  1863. X      
  1864. X      if (arrayp == arraymax)
  1865. X        {
  1866. X          int diff = arraysize;
  1867. X          
  1868. X          arraysize += 300;
  1869. X          array = (char **)realloc((void *)array, arraysize);
  1870. X          arrayp = array + diff;
  1871. X        }
  1872. X    }
  1873. X
  1874. X      /* free((void *)file); */
  1875. X    }
  1876. X
  1877. X  while ((array <= arrayp) && *array)
  1878. X    {
  1879. X      mood(*array);
  1880. X      array++;
  1881. X    }
  1882. X  
  1883. X  return 0;
  1884. X}
  1885. X
  1886. void die(int stat)
  1887. X{
  1888. X  perror(program);
  1889. X  exit(stat);
  1890. X}
  1891. X
  1892. X/************************************************************************
  1893. X * funciton:    warn();                                                 *
  1894. X *                                                                      *
  1895. X * object:      print warning messages on failed system calls        *
  1896. X *                                                                      *
  1897. X * Erik Quanstrom                                                       *
  1898. X * 25. Januar 1992                                                      *
  1899. X ************************************************************************/
  1900. void warn(void)
  1901. X{
  1902. X  long t = time(NULL);
  1903. X  static char s[20];
  1904. X  
  1905. X  perror((char *)sprintf(s, "%15.15s ", (char *)(ctime(&t) + 4)));
  1906. X}
  1907. X
  1908. X/************************************************************************
  1909. X * funciton:    strdup();                                               *
  1910. X *                                                                      *
  1911. X * object:      malloc and copy a string                                *
  1912. X *                                                                      *
  1913. X * Erik Quanstrom                                                       *
  1914. X * 20. Juli 1991                                                        *
  1915. X ************************************************************************/
  1916. char *strdup(char *foo)
  1917. X{
  1918. X  char *tmp = (char *)malloc(sizeof(char) * strlen(foo) ),
  1919. X       *p = tmp;
  1920. X
  1921. X  /* make sure to copy the NULL */
  1922. X  do
  1923. X    *tmp++ = *foo;
  1924. X  while ( *foo++ );
  1925. X
  1926. X  return p;
  1927. X}
  1928. X
  1929. X/************************************************************************
  1930. X * funciton:    concat();                        *
  1931. X *                                     *
  1932. X * object:    malloc and copy    2 strings --- and don't die or do     *
  1933. X *        aything else anti-social if either is null        *
  1934. X *                                     *
  1935. X * Erik Quanstrom                             *
  1936. X * 20. Juli 1991                            *
  1937. X ************************************************************************/
  1938. char *concat( char *a, char *b )
  1939. X{
  1940. X  char *tmp, *p;
  1941. X  
  1942. X  if ( !a ) 
  1943. X    if ( b )
  1944. X      return strdup(b);
  1945. X    else
  1946. X      return b;
  1947. X  
  1948. X  if ( !b ) 
  1949. X    return strdup(a);
  1950. X  
  1951. X  p = tmp = (char *)malloc( sizeof (char) * (strlen(a) + strlen(b) + 2) );
  1952. X  
  1953. X  while ( *a )
  1954. X    *tmp++ = *a++;
  1955. X  
  1956. X  /* make sure to copy the NULL */
  1957. X  do
  1958. X    *tmp++ = *b;
  1959. X  while ( *b++ );
  1960. X  
  1961. X  return p;
  1962. X}
  1963. END_OF_FILE
  1964. if test 12721 -ne `wc -c <'fmood.c'`; then
  1965.     echo shar: \"'fmood.c'\" unpacked with wrong size!
  1966. fi
  1967. # end of 'fmood.c'
  1968. fi
  1969. if test -f 'friends.1' -a "${1}" != "-c" ; then 
  1970.   echo shar: Will not clobber existing file \"'friends.1'\"
  1971. else
  1972. echo shar: Extracting \"'friends.1'\" \(1436 characters\)
  1973. sed "s/^X//" >'friends.1' <<'END_OF_FILE'
  1974. X.TH friends 1 " 2. December 1991"
  1975. X.SH NAME
  1976. friends, rfriends 0.90 \- print out friends logged in.
  1977. X.SH SYNOPSIS
  1978. friends
  1979. X.LP
  1980. rfriends
  1981. X.SH DESCRIPTION
  1982. X.B Friends
  1983. displays the login name, full name, terminal name (prepended with a `*'
  1984. if write permission is denied), idle time, login time, and location
  1985. X(comment field in /etc/ttytab for local users, hostname for remote
  1986. users) for all people listed in ~/.friends.
  1987. X
  1988. Idle time is minutes if it is a single integer, hours and minutes if a
  1989. X':' is present, or days and hours if a d is present
  1990. X
  1991. X.B Rfriends
  1992. displays 
  1993. X.BR rwho (1)
  1994. information for all peole listed in ~/.friends.
  1995. X.SH BUGS
  1996. X.B Friends 
  1997. is too slow. See 
  1998. X.B ffriends (1) 
  1999. for a faster but more terse version.
  2000. X.SH "SEE ALSO"
  2001. X.BR mood (1),
  2002. X.BR moodmail (1),
  2003. X.BR fmood (1),
  2004. X.BR ffriends (1),
  2005. X.BR friends (5),
  2006. X.SH FILES
  2007. X.PD 0
  2008. X.TP 20
  2009. X.B ~/.friends
  2010. friends file
  2011. X.TP
  2012. X.B /etc/utmp
  2013. who is logged in
  2014. X.TP
  2015. X.B /etc/passwd
  2016. for users' names
  2017. X.TP
  2018. X.B /var/adm/lastlog
  2019. last login times
  2020. X.TP
  2021. X.B /etc/ttytab
  2022. terminal locations
  2023. X.PD
  2024. X.SH AUTHOR
  2025. Copyright (C) 1991, 1992 by Erik Quanstrom
  2026. X
  2027. Permission to use, copy, modify, and distribute this software and its
  2028. documentation for any purpose and without fee is hereby granted, provided
  2029. that the above copyright notice appear in all copies and that both that
  2030. copyright notice and this permission notice appear in supporting
  2031. documentation.  This software is provided ``as is'' without express or
  2032. implied warranty.
  2033. END_OF_FILE
  2034. if test 1436 -ne `wc -c <'friends.1'`; then
  2035.     echo shar: \"'friends.1'\" unpacked with wrong size!
  2036. fi
  2037. # end of 'friends.1'
  2038. fi
  2039. if test -f 'friends.5' -a "${1}" != "-c" ; then 
  2040.   echo shar: Will not clobber existing file \"'friends.5'\"
  2041. else
  2042. echo shar: Extracting \"'friends.5'\" \(574 characters\)
  2043. sed "s/^X//" >'friends.5' <<'END_OF_FILE'
  2044. X.TH friends 5 " 2. December 1991"
  2045. X.SH NAME
  2046. friends \- the friends file specification
  2047. X.SH SYNOPSIS
  2048. X~/.friends
  2049. X.SH DESCRIPTION
  2050. The 
  2051. X.I friends
  2052. file format is used by the programs 
  2053. X.BR friends (1)
  2054. and 
  2055. X.BR mood(1) 
  2056. for specifying a users friends. The 
  2057. X.I friends
  2058. file (usually ~/.friends) contains the login names of a users friends,
  2059. seperated by whitespace (newline, tab, or space). The entries in a
  2060. friends file may be in any order.
  2061. X.SH "SEE ALSO"
  2062. X.BR moodmail (1), 
  2063. X.BR friends(1),
  2064. X.BR mood(1) 
  2065. X.SH FILES
  2066. X.PD 0
  2067. X.TP 20
  2068. X.B ~/.mood 
  2069. mood file
  2070. X.TP 20
  2071. X.B ~/.friends
  2072. friends file
  2073. END_OF_FILE
  2074. if test 574 -ne `wc -c <'friends.5'`; then
  2075.     echo shar: \"'friends.5'\" unpacked with wrong size!
  2076. fi
  2077. # end of 'friends.5'
  2078. fi
  2079. if test -f 'friends.d' -a "${1}" != "-c" ; then 
  2080.   echo shar: Will not clobber existing file \"'friends.d'\"
  2081. else
  2082. echo shar: Extracting \"'friends.d'\" \(739 characters\)
  2083. sed "s/^X//" >'friends.d' <<'END_OF_FILE'
  2084. X#!/bin/sh
  2085. X#########################################################################
  2086. X# file:     friends                            #
  2087. X#                                    #
  2088. X# object:    are any of my friends on the system?            #
  2089. X#                                    #
  2090. X# Erik Quanstrom                            #
  2091. X# 10. Juli 1991                                #
  2092. X#########################################################################
  2093. h=/usr/local/bin
  2094. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$h/SPARCbin
  2095. X
  2096. case $0 in
  2097. X  friends | */friends)
  2098. X    p=finger;
  2099. X    program='friends';;
  2100. X  rfriends | */rfriends)
  2101. X    p=rwho;
  2102. X    program='rfriends';
  2103. esac
  2104. X
  2105. if test '!' -f $HOME/.friends; then
  2106. X  echo $program: '$'HOME/.friends not found. 2>&1;
  2107. fi
  2108. X
  2109. case $# in 
  2110. X  0) ;;
  2111. X  *) 
  2112. X     echo usage: $program 1>&2;
  2113. X     exit 1;;
  2114. esac
  2115. X
  2116. X$p | egrep -e "`tr ' ' '\012' < $HOME/.friends `"
  2117. END_OF_FILE
  2118. if test 739 -ne `wc -c <'friends.d'`; then
  2119.     echo shar: \"'friends.d'\" unpacked with wrong size!
  2120. fi
  2121. # end of 'friends.d'
  2122. fi
  2123. if test -f 'geeks.1' -a "${1}" != "-c" ; then 
  2124.   echo shar: Will not clobber existing file \"'geeks.1'\"
  2125. else
  2126. echo shar: Extracting \"'geeks.1'\" \(956 characters\)
  2127. sed "s/^X//" >'geeks.1' <<'END_OF_FILE'
  2128. X.TH geeks 1 " 17. January 1992"
  2129. X.SH NAME
  2130. geeks 0.90 \- report on the top users of the week.
  2131. X.SH SYNOPSIS
  2132. geeks [\-n
  2133. X.I number
  2134. X]
  2135. X.SH DESCRIPTION
  2136. X.B Geeks 
  2137. querries the system time as to the total login time of each user on
  2138. the local machine and
  2139. then reports on the top 
  2140. X.I number
  2141. X``geeks.'' The default for 
  2142. X.I number 
  2143. is ten.
  2144. X
  2145. X.SH BUGS
  2146. X.B Geeks
  2147. is too slow.
  2148. X
  2149. X.SH "SEE ALSO"
  2150. X.BR mood (1),
  2151. X.BR moodmail (1),
  2152. X.BR fmood (1),
  2153. X.BR ffriends (1),
  2154. X.BR friends (5),
  2155. X.BR theirmail (1)
  2156. X
  2157. X.SH FILES
  2158. X.PD 0
  2159. X.TP 20
  2160. X.B /usr/spool/mail/*
  2161. mail files
  2162. X
  2163. X.SH AUTHOR
  2164. Copyright (C) 1991, 1992 by Erik Quanstrom
  2165. X
  2166. Permission to use, copy, modify, and distribute this software and its
  2167. documentation for any purpose and without fee is hereby granted, provided
  2168. that the above copyright notice appear in all copies and that both that
  2169. copyright notice and this permission notice appear in supporting
  2170. documentation.  This software is provided ``as is'' without express or
  2171. implied warranty.
  2172. END_OF_FILE
  2173. if test 956 -ne `wc -c <'geeks.1'`; then
  2174.     echo shar: \"'geeks.1'\" unpacked with wrong size!
  2175. fi
  2176. # end of 'geeks.1'
  2177. fi
  2178. if test -f 'geeks.d' -a "${1}" != "-c" ; then 
  2179.   echo shar: Will not clobber existing file \"'geeks.d'\"
  2180. else
  2181. echo shar: Extracting \"'geeks.d'\" \(1137 characters\)
  2182. sed "s/^X//" >'geeks.d' <<'END_OF_FILE'
  2183. X#!/bin/sh
  2184. X#########################################################################
  2185. X# file:     geeks                            #
  2186. X#                                    #
  2187. X# object:    print out the n geekiest users                #
  2188. X#                                    #
  2189. X# usage:    geeks [-n geeks]                     #
  2190. X#        geeks -geeks                        #
  2191. X#                                    #
  2192. X# Erik Quanstrom                            #
  2193. X# 10. Juli 1991                                #
  2194. X#########################################################################
  2195. h=/home/accserv1/stub/e/quanstro
  2196. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$h/SPARCbin
  2197. X
  2198. case $# in
  2199. X 0) n=10;;
  2200. X 1) n=`echo $1 | sed 's/-//'`
  2201. X    if echo $n | egrep -v '[0-9]+' > /dev/null; then
  2202. X      echo "usage: $0 [-n geeks]";
  2203. X      exit 1;
  2204. X    fi;;
  2205. X 2) case $1 in 
  2206. X      -n) if echo $2 | egrep '[0-9]+' > /dev/null; then
  2207. X         n=$2;
  2208. X          else
  2209. X        echo "usage: $0 [-n geeks]";
  2210. X        exit 1;
  2211. X          fi;;
  2212. X       *) echo "usage: $0 [-n geeks]";
  2213. X      exit 1;;
  2214. X    esac;;
  2215. X *) echo "usage: $0 [-n geeks]"
  2216. X    exit 1;;
  2217. esac
  2218. X    
  2219. X/usr/etc/ac -p | awk ' /^\ttotal/ { exit; }
  2220. X{
  2221. X  if (NF == 1)
  2222. X    print substr($1, 1, 8)" "substr($1, 9, 10);
  2223. X  else 
  2224. X    {
  2225. X      if ( length($1) == 8 )
  2226. X    print $1" "$2;
  2227. X      else
  2228. X    print $1"     "$2;
  2229. X    }
  2230. X}' | sort +1rn | head -$n;
  2231. X
  2232. exit 0;
  2233. END_OF_FILE
  2234. if test 1137 -ne `wc -c <'geeks.d'`; then
  2235.     echo shar: \"'geeks.d'\" unpacked with wrong size!
  2236. fi
  2237. # end of 'geeks.d'
  2238. fi
  2239. if test ! -d 'hist' ; then
  2240.     echo shar: Creating directory \"'hist'\"
  2241.     mkdir 'hist'
  2242. fi
  2243. if test -f 'in.rwhod.8' -a "${1}" != "-c" ; then 
  2244.   echo shar: Will not clobber existing file \"'in.rwhod.8'\"
  2245. else
  2246. echo shar: Extracting \"'in.rwhod.8'\" \(1760 characters\)
  2247. sed "s/^X//" >'in.rwhod.8' <<'END_OF_FILE'
  2248. X.TH in.rwhod 8 "14. January 1992"
  2249. X.SH NAME
  2250. in.rwhod 0.90 \- a lazy daemon for reporting on remote users.
  2251. X.SH SYNOPSIS
  2252. in.rwhod [\-d]  [\-c 
  2253. X.IR server ]
  2254. X.SH DESCRIPTION
  2255. X.B In.rwhod
  2256. lurks in the background, in either server or client (\-c) mode. If 
  2257. X.B in.rwhod
  2258. receives a connection in server mode, it first determines if the
  2259. connection is a query or a report. A query is recognized by the first
  2260. byte of the transmision being a `*.' (One can use 
  2261. X.BR telnet (1) 
  2262. instead of 
  2263. X.B rwho (1)
  2264. to connect to the server and send a `*' and then a 
  2265. X.SC CR
  2266. on a line to recieve a report.) If 
  2267. X.B In.rwhod 
  2268. is asked for a report, it is sent out on the socket. If it is provided
  2269. with a report (the contents of /etc/termcap),  this is remembered. 
  2270. X
  2271. In client mode,
  2272. X.B in.rwhod
  2273. send a report each time /etc/utmp is updated, but not more often than
  2274. once a minute.
  2275. X
  2276. X.SH BUGS
  2277. X.B In.rwhod 
  2278. assumes that the clients are alwats sending current and correct
  2279. reports. In addition, there is no authentication of either remote querries
  2280. or client servers.
  2281. X
  2282. X.SH "SEE ALSO" 
  2283. X.BR friends (1), 
  2284. X.BR friends (5), 
  2285. X.BR moodmail (1), 
  2286. X.BR mood (1), 
  2287. X.BR fmood (1)
  2288. X
  2289. X.SH files
  2290. X.PD 0
  2291. X.TP 20
  2292. X.B ~/.friends
  2293. friends file
  2294. X.TP
  2295. X.B /etc/utmp
  2296. who is logged in
  2297. X.TP
  2298. X.B /etc/passwd
  2299. for users' names
  2300. X.TP
  2301. X.B /var/adm/lastlog
  2302. last login times
  2303. X.TP
  2304. X.B /etc/ttytab
  2305. terminal locations
  2306. X.PD
  2307. X.SH AUTHOR
  2308. Copyright (C) 1991, 1992 by Erik Quanstrom
  2309. X
  2310. Permission to use, copy, modify, and distribute this software and its
  2311. documentation for any purpose and without fee is hereby granted, provided
  2312. that the above copyright notice appear in all copies and that both that
  2313. copyright notice and this permission notice appear in supporting
  2314. documentation.  This software is provided ``as is'' without express or
  2315. implied warranty.
  2316. X
  2317. END_OF_FILE
  2318. if test 1760 -ne `wc -c <'in.rwhod.8'`; then
  2319.     echo shar: \"'in.rwhod.8'\" unpacked with wrong size!
  2320. fi
  2321. # end of 'in.rwhod.8'
  2322. fi
  2323. if test -f 'in.rwhod.c' -a "${1}" != "-c" ; then 
  2324.   echo shar: Will not clobber existing file \"'in.rwhod.c'\"
  2325. else
  2326. echo shar: Extracting \"'in.rwhod.c'\" \(13611 characters\)
  2327. sed "s/^X//" >'in.rwhod.c' <<'END_OF_FILE'
  2328. X/************************************************************************
  2329. X * file:    in.rwhod.c                        *
  2330. X *                                    *
  2331. X * object:    to provide rwho information in a way that makes the     *
  2332. X *        least demands on the network _while_ remaining         *
  2333. X *        fully dynamic. That is, hosts should be added         *
  2334. X *         automatically and removed automatically by in.rwhod.    *
  2335. X *        To accomplish this, it is necessary to            *
  2336. X *         1) not have ruptime information                *
  2337. X *        2) to leave it up to the clients to pass on new     *
  2338. X *           information using lazy updating.            *
  2339. X *                                    *
  2340. X * Copyright (C) Erik Quanstrom, 1992                    *
  2341. X * Under the terms expressed in the manual page                *
  2342. X *                                    *
  2343. X * Erik Quanstrom                            *
  2344. X * 17. Januar 1992                            *
  2345. X ************************************************************************/
  2346. X#include <stdio.h>
  2347. X#include <sys/types.h>
  2348. X#include <sys/file.h>
  2349. X#include <sys/param.h>
  2350. X#include <sys/socket.h>
  2351. X#include <sys/stat.h>
  2352. X#include <sys/time.h>
  2353. X#include <netdb.h>
  2354. X#include <netinet/in.h>
  2355. X#include <utmp.h>
  2356. X#include <lastlog.h>
  2357. X
  2358. X#define PORT 5002             /* this is really arbitrary */
  2359. X#define BSIZE 1024 * 8
  2360. X#define SPECIAL '*'
  2361. X#define FLAG '-'
  2362. X#define INFO_REQUEST '*'
  2363. X#define INFO_TRANSMISSION '#'
  2364. X#define INFO_TRANSMISSIONs "#"
  2365. X
  2366. X#ifndef nonuser
  2367. X#define nonuser(ut) ((ut).ut_host[0] == 0 && \
  2368. X    strncmp((ut).ut_line, "tty", 3) == 0 && ((ut).ut_line[3] == 'p' \
  2369. X                          || (ut).ut_line[3] == 'q' \
  2370. X                          || (ut).ut_line[3] == 'r' \
  2371. X                          || (ut).ut_line[3] == 's'))
  2372. X
  2373. X#endif /* !nonuser */
  2374. X
  2375. X/* this is a hack for the NeXT */
  2376. X
  2377. X#define HOST_LEN 64
  2378. X
  2379. X/* end of hack for the NeXT */
  2380. X
  2381. typedef struct sockaddr SOCK;
  2382. typedef struct sockaddr_in SOCK_IN; 
  2383. X
  2384. typedef struct utmp Utmp;
  2385. X
  2386. typedef enum 
  2387. X{
  2388. X  false,
  2389. X  true
  2390. X} boolean;
  2391. X
  2392. typedef struct 
  2393. X{
  2394. X  char *machine;
  2395. X  Utmp *utmp;
  2396. X  int size;    /* this is assumed to be volatile */
  2397. X  int reserved; /* therefore, so is this          */
  2398. X} Who;
  2399. X
  2400. void usage(void);
  2401. int open_socket(int port);
  2402. int open_socket_send(char *host, int port);
  2403. void process_connection(int s);
  2404. int wait_for_connection(int s);
  2405. int lazy_client(char *host, int port);
  2406. int client_report(char *server, int port);
  2407. int client_wait(void);
  2408. int info_request(int s);
  2409. X
  2410. void die(int c);
  2411. void warn(void);
  2412. void debug(FILE *f, char *format);
  2413. X
  2414. void *xmalloc(size_t size);
  2415. void *xrealloc(void *object, size_t size);
  2416. X
  2417. char *strdup(char *s);
  2418. X
  2419. Who *who_alloc(void);
  2420. Who *who_lookup(char *machine);
  2421. Who *who_add(char *machine, Utmp *utmp, int size, int alloc);
  2422. X
  2423. char *program;
  2424. Utmp *users = NULL;
  2425. int  utmp_size;
  2426. Who **who = NULL;
  2427. int dashd = 0;
  2428. X
  2429. int main(int argc, char **argv)
  2430. X{
  2431. X  int s;
  2432. X  int port = PORT;
  2433. X
  2434. X  program = *argv;
  2435. X  
  2436. X  while (++argv && *argv && **argv)
  2437. X    {
  2438. X      if (**argv == FLAG)
  2439. X    while (++*argv && **argv)
  2440. X      {
  2441. X        switch (**argv)
  2442. X          {
  2443. X          case 'c':
  2444. X        if (*(*argv +1) || !*(++argv))
  2445. X          usage();
  2446. X
  2447. X        lazy_client(*argv, port);
  2448. X          case 'd':
  2449. X        dashd++;
  2450. X        break;
  2451. X          case 's':
  2452. X        break;
  2453. X          default:
  2454. X        usage();
  2455. X        /* NOT_REACHED */
  2456. X          }
  2457. X      }
  2458. X    }
  2459. X
  2460. X  if (argv && *argv)
  2461. X    usage();
  2462. X  
  2463. X  if ((s = open_socket( port )) == -1)
  2464. X    exit(1);
  2465. X
  2466. X  do
  2467. X    process_connection(wait_for_connection(s));
  2468. X  while (1);
  2469. X
  2470. X  /* NOT_REACHED */
  2471. X
  2472. X  close(s);
  2473. X  return 0;
  2474. X}
  2475. X
  2476. X/************************************************************************
  2477. X * function:    usage()                            *
  2478. X *                                     *
  2479. X * object:     print out the usage message                *
  2480. X *                                     *
  2481. X * Erik Quanstrom                            *
  2482. X * 14. Jaunar 1992                            *
  2483. X ************************************************************************/
  2484. void usage(void)
  2485. X{
  2486. X  fprintf(stderr, "usage: %s [-d] [-c server]\n", program);
  2487. X  exit(1);
  2488. X}
  2489. X
  2490. X/************************************************************************
  2491. X * function:    wait_for_connection()                    *
  2492. X *                                     *
  2493. X * object:     sit and wait for a connection                *
  2494. X *                                     *
  2495. X * Erik Quanstrom                            *
  2496. X * 2. Oktober 1991                            *
  2497. X ************************************************************************/
  2498. int wait_for_connection(int s)
  2499. X{
  2500. X  int new,
  2501. X      newlen = sizeof(SOCK);
  2502. X  
  2503. X  SOCK *new_socket = (SOCK *)xmalloc(newlen);
  2504. X  
  2505. X  if ((new = accept(s, new_socket, &newlen)) < 0)
  2506. X    die(1);
  2507. X  
  2508. X  return new;
  2509. X}
  2510. X
  2511. X/************************************************************************
  2512. X * function:    process_connection()                    *
  2513. X *                                     *
  2514. X * object:     return the requested information across the socket    *
  2515. X *                                     *
  2516. X * Erik Quanstrom                            *
  2517. X * 2. Oktober 1991                            *
  2518. X ************************************************************************/
  2519. void process_connection(int s)
  2520. X{
  2521. X  FILE *f;
  2522. X  char c;
  2523. X  Who *w;
  2524. X  static char *machine = NULL;
  2525. X  Utmp *utmpp;
  2526. X  int tmp;
  2527. X  
  2528. X  read(s, &c, 1);
  2529. X
  2530. X  if (c == INFO_REQUEST)
  2531. X    {
  2532. X      debug(stderr, "info request\n");
  2533. X      info_request(s);
  2534. X    }
  2535. X  else
  2536. X    {
  2537. X      if (!machine)
  2538. X    machine = (char *)xmalloc(HOST_LEN * sizeof(char));
  2539. X  
  2540. X      if (!(f = fdopen(s, "r")))
  2541. X    {
  2542. X      warn();
  2543. X      close (s);
  2544. X      return;
  2545. X    }
  2546. X
  2547. X      if (!fread(machine, sizeof(char), HOST_LEN, f))
  2548. X    {
  2549. X      warn();
  2550. X      fclose(f);
  2551. X      close(s);
  2552. X      return;
  2553. X    }
  2554. X
  2555. X      if (!(w = who_lookup(machine)))
  2556. X    {
  2557. X      w = who_add((char *)NULL, (Utmp *)NULL, 0, 54);
  2558. X      w->utmp = (Utmp *)xmalloc(sizeof(Utmp) * 54);
  2559. X      w->machine = strdup(machine);
  2560. X    }
  2561. X
  2562. X      utmpp = w->utmp;
  2563. X      w->size = fread(utmpp, sizeof(Utmp), w->reserved, f);
  2564. X
  2565. X      while (!feof(f))
  2566. X    {
  2567. X      tmp = (utmpp - w->utmp) + 54;
  2568. X      
  2569. X      w->reserved += 54;
  2570. X        
  2571. X      utmpp = w->utmp = (Utmp *)realloc((void *)w->utmp, 
  2572. X                        w->reserved * sizeof(Utmp));
  2573. X      utmpp += tmp;
  2574. X      w->size += fread(utmpp, sizeof(Utmp), 54, f);
  2575. X    }
  2576. X  
  2577. X      fflush(f);
  2578. X      fclose(f);
  2579. X    }
  2580. X
  2581. X  close (s);
  2582. X}  
  2583. X
  2584. int info_request(int s)
  2585. X{
  2586. X  FILE *f = fdopen(s, "w");
  2587. X  Who **w = who;
  2588. X  Utmp *u;
  2589. X  Utmp *u_top;
  2590. X
  2591. X  static char *fmachine = NULL;
  2592. X  
  2593. X  if (!fmachine)
  2594. X    fmachine = (char *)xmalloc(HOST_LEN * sizeof(char));
  2595. X  
  2596. X  while (w && *w)
  2597. X    {
  2598. X      u_top = u = ((Who *)*w)->utmp;
  2599. X      u_top += ((Who *)*w)->size;
  2600. X     
  2601. X      sprintf(fmachine, "[%-15.15s]  ", ((Who *)*w)->machine);
  2602. X
  2603. X      do
  2604. X    if (u->ut_name[0] && !(nonuser(*u)))
  2605. X      {
  2606. X        fwrite(fmachine, 15 + 4, 1, f);
  2607. X        fprintf(f, "%-8.8s %-8s (%-16.16s)\n", 
  2608. X            u->ut_name, u->ut_line, u->ut_host);
  2609. X      }
  2610. X      while (++u <= u_top);
  2611. X      
  2612. X      w++;
  2613. X    }
  2614. X  
  2615. X  fflush(f);
  2616. X  fclose(f);
  2617. X
  2618. X  return 0;
  2619. X}
  2620. X
  2621. X/************************************************************************
  2622. X * function:    lazy_client()                        *
  2623. X *                                     *
  2624. X * object:     be a lazy client                    *
  2625. X *                                     *
  2626. X * Erik Quanstrom                            *
  2627. X * 2. Oktober 1991                            *
  2628. X ************************************************************************/
  2629. int lazy_client(char *server, int port)
  2630. X{
  2631. X  do 
  2632. X    {
  2633. X      client_wait();
  2634. X      client_report(server, port);
  2635. X    }
  2636. X  while (1);
  2637. X  
  2638. X  /* NOT_REACHED */
  2639. X  return 0;
  2640. X}
  2641. X
  2642. int client_report(char *server, int port)
  2643. X{
  2644. X  int s, utmp;
  2645. X  static char *host = NULL;
  2646. X
  2647. X  if ((s = open_socket_send(server, port)) == -1)
  2648. X    return -1;
  2649. X      
  2650. X  debug(stderr, "sending report\n");
  2651. X  
  2652. X  if (!host)
  2653. X    {
  2654. X      host = (char *)xmalloc(HOST_LEN * sizeof(char));
  2655. X      gethostname(host, HOST_LEN);
  2656. X    }
  2657. X
  2658. X  if ((utmp = open("/etc/utmp", 0)) < 0)
  2659. X    die(1);
  2660. X
  2661. X  /* preformace bug: this should be one write with the HOST_LEN
  2662. X     snuck in at the beginning
  2663. X   */
  2664. X  read(utmp, users, utmp_size);
  2665. X
  2666. X  write(s, INFO_TRANSMISSIONs, 1); /* type */
  2667. X  write(s, host, HOST_LEN);
  2668. X  write(s, users, utmp_size);
  2669. X  
  2670. X  close(s);
  2671. X  close(utmp);
  2672. X
  2673. X  debug(stderr, "finished \n");
  2674. X  return 0;
  2675. X}
  2676. X
  2677. int client_wait(void)
  2678. X{
  2679. X  static long t = 0;
  2680. X  struct stat buf;
  2681. X  boolean changed = false;
  2682. X  
  2683. X  for (;;)
  2684. X    {
  2685. X      if (stat("/etc/utmp", &buf))
  2686. X    die(1);
  2687. X
  2688. X      if (buf.st_mtime > t) 
  2689. X    {
  2690. X      users = (Utmp *)xmalloc(utmp_size = (int)buf.st_size); /* ick! */
  2691. X
  2692. X      t = buf.st_mtime;
  2693. X      break;
  2694. X    }
  2695. X
  2696. X      sleep(30);
  2697. X    }
  2698. X  return 0;
  2699. X}
  2700. X
  2701. X/************************************************************************
  2702. X * function:    open_socket()                        *
  2703. X *                                     *
  2704. X * object:     open a internet domain socket for connections        *
  2705. X *                                     *
  2706. X * Erik Quanstrom                            *
  2707. X * 2. Oktober 1991                            *
  2708. X ************************************************************************/
  2709. int open_socket(int port)
  2710. X{
  2711. X  int s;
  2712. X  SOCK_IN *sin = (SOCK_IN *)xmalloc(sizeof(SOCK_IN));
  2713. X
  2714. X  if ( (s = socket(PF_INET, SOCK_STREAM, 0)) == -1 )
  2715. X    {
  2716. X      warn();
  2717. X      return -1;
  2718. X    }
  2719. X
  2720. X  sin->sin_addr.s_addr = INADDR_ANY;
  2721. X  sin->sin_family = AF_INET;
  2722. X  sin->sin_port = htons( port );
  2723. X
  2724. X  if (bind(s, sin, sizeof(SOCK_IN)) < 0)
  2725. X    die(1);
  2726. X
  2727. X  if (listen(s, 5))
  2728. X    die(1);
  2729. X  
  2730. X  return s;
  2731. X}  
  2732. X
  2733. X/************************************************************************
  2734. X * function:    open_socket_send()                    *
  2735. X *                                     *
  2736. X * object:     open a internet domain socket for sending info        *
  2737. X *                                     *
  2738. X * Erik Quanstrom                            *
  2739. X * 2. Oktober 1991                            *
  2740. X ************************************************************************/
  2741. int open_socket_send(char *host, int port)
  2742. X{
  2743. X  struct hostent *hp;
  2744. X  SOCK_IN *sin = (SOCK_IN *)xmalloc(sizeof(SOCK_IN));
  2745. X  int s;
  2746. X
  2747. X  if ( (sin->sin_addr.s_addr = inet_addr( host )) != -1)
  2748. X    sin->sin_family = AF_INET;
  2749. X  else
  2750. X    if (hp = gethostbyname(host)) 
  2751. X      {
  2752. X    sin->sin_family = hp->h_addrtype;
  2753. X    bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
  2754. X      } 
  2755. X    else 
  2756. X      {
  2757. X    fprintf(stderr, "unknown host %s\n", host);
  2758. X    exit(1);
  2759. X      }
  2760. X  
  2761. X  sin->sin_port = htons( port );
  2762. X  
  2763. X  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
  2764. X    {
  2765. X      warn();
  2766. X      return -1;
  2767. X    }
  2768. X  
  2769. X  if (connect(s, sin, sizeof(SOCK_IN)) < 0)
  2770. X    {
  2771. X      warn();
  2772. X      close(s);
  2773. X      return -1;
  2774. X    }
  2775. X  
  2776. X  return s;
  2777. X}
  2778. X
  2779. Who *who_alloc(void)
  2780. X{
  2781. X  static int who_size;
  2782. X  static int who_alloc = 0;
  2783. X  static Who **p = NULL;
  2784. X
  2785. X  who_alloc++;
  2786. X  
  2787. X  /* who is a ** so this may only increase by one each time */
  2788. X  if (!who)
  2789. X    {
  2790. X      who_size = 20/*# of hosts*/; 
  2791. X      p = who = (Who **)xmalloc(who_size * sizeof(Who *));
  2792. X    }
  2793. X  else if (who_size < who_alloc)
  2794. X    {
  2795. X      who_size += 20;
  2796. X      p = who = (Who **)realloc((void *)who, who_size * sizeof(Who *));
  2797. X      p += who_size - 20;
  2798. X    }
  2799. X
  2800. X  *p = (Who *)xmalloc(sizeof(Who));
  2801. X  
  2802. X  p++;
  2803. X  *p = NULL;
  2804. X  
  2805. X  return *(p - 1);
  2806. X}
  2807. X
  2808. Who *who_lookup(char *machine)
  2809. X{
  2810. X  Who **w = who;
  2811. X
  2812. X  /* this takes care of the starting condition */
  2813. X  if (!w)
  2814. X    return NULL;
  2815. X  
  2816. X  while (*w && strcmp((*w)->machine, machine))
  2817. X    w++;
  2818. X
  2819. X  return *w;
  2820. X}
  2821. X
  2822. Who *who_add(char *machine, Utmp *utmp, int size, int reserved)
  2823. X{
  2824. X  Who *w = who_alloc(); /* get a slot in the ptr to utmp list */
  2825. X
  2826. X  w->machine = machine;
  2827. X  w->utmp = utmp;
  2828. X  w->size = size;
  2829. X  w->reserved = reserved;
  2830. X
  2831. X  return w;
  2832. X}
  2833. X
  2834. X/************************************************************************
  2835. X * funciton:    die();                                                  *
  2836. X *                                                                      *
  2837. X * object:      print out error message and exit.            *
  2838. X *                                                                      *
  2839. X * Erik Quanstrom                                                       *
  2840. X * 25. Januar 1992                                                      *
  2841. X ************************************************************************/  
  2842. void die(int c)
  2843. X{
  2844. X  perror(program);
  2845. X  exit(c);
  2846. X}
  2847. X
  2848. X/************************************************************************
  2849. X * funciton:    debug();                                                *
  2850. X *                                                                      *
  2851. X * object:      print debugging information if debugging is turned on    *
  2852. X *                                                                      *
  2853. X * Erik Quanstrom                                                       *
  2854. X * 25. Januar 1992                                                      *
  2855. X ************************************************************************/
  2856. void debug(FILE *f, char *format)
  2857. X{
  2858. X  long t;
  2859. X  
  2860. X  if (!dashd)
  2861. X    return;
  2862. X  
  2863. X  t = time(NULL);
  2864. X  
  2865. X  fprintf(f, "%15.15s %s", (char *)(ctime(&t) + 4), format);
  2866. X}
  2867. X
  2868. X/************************************************************************
  2869. X * funciton:    warn();                                                 *
  2870. X *                                                                      *
  2871. X * object:      print warning messages on failed system calls        *
  2872. X *                                                                      *
  2873. X * Erik Quanstrom                                                       *
  2874. X * 25. Januar 1992                                                      *
  2875. X ************************************************************************/
  2876. void warn(void)
  2877. X{
  2878. X  long t = time(NULL);
  2879. X  static char s[20];
  2880. X  
  2881. X  perror((char *)sprintf(s, "%15.15s ", (char *)(ctime(&t) + 4)));
  2882. X}
  2883. X
  2884. X/************************************************************************
  2885. X * funciton:    strdup();                                               *
  2886. X *                                                                      *
  2887. X * object:      malloc and copy a string                                *
  2888. X *                                                                      *
  2889. X * Erik Quanstrom                                                       *
  2890. X * 20. Juli 1991                                                        *
  2891. X ************************************************************************/
  2892. char *strdup(char *foo)
  2893. X{
  2894. X  char *tmp, *p;
  2895. X
  2896. X  /* make sure to copy the NULL */
  2897. X  if (p = tmp = (char *)xmalloc (sizeof(char) * (strlen(foo) + 1)))
  2898. X    while (*tmp++ = *foo++)
  2899. X      ;
  2900. X  
  2901. X  return p;
  2902. X}
  2903. X
  2904. void *xmalloc(size_t size)
  2905. X{
  2906. X  void *tmp;
  2907. X  
  2908. X  if (!(tmp = (void *)malloc(size)))
  2909. X    die(1);
  2910. X  
  2911. X  return tmp;
  2912. X}
  2913. X
  2914. void *xrealloc(void *object, size_t size)
  2915. X{
  2916. X  void *tmp;
  2917. X  
  2918. X  if (!object)
  2919. X    tmp = (void *)malloc(size);
  2920. X  else
  2921. X    tmp = (void *)realloc(object, size);
  2922. X  
  2923. X  if (!tmp)
  2924. X    die(1);
  2925. X  
  2926. X  return tmp;
  2927. X}
  2928. END_OF_FILE
  2929. if test 13611 -ne `wc -c <'in.rwhod.c'`; then
  2930.     echo shar: \"'in.rwhod.c'\" unpacked with wrong size!
  2931. fi
  2932. # end of 'in.rwhod.c'
  2933. fi
  2934. if test -f 'mitime.d' -a "${1}" != "-c" ; then 
  2935.   echo shar: Will not clobber existing file \"'mitime.d'\"
  2936. else
  2937. echo shar: Extracting \"'mitime.d'\" \(752 characters\)
  2938. sed "s/^X//" >'mitime.d' <<'END_OF_FILE'
  2939. X#!/bin/sh 
  2940. X#########################################################################
  2941. X# function:    mitime                            #
  2942. X#                                    #
  2943. X# object:    imiatte /usr/etc/ac -p                     #
  2944. X#                                     #
  2945. X# Erik Quanstrom                            #
  2946. X# 25. M"arz 1992                            #
  2947. X#########################################################################
  2948. h=/usr/local
  2949. PATH=/bin:/usr/bin:/usr/local/bin:/usr/ucb
  2950. X
  2951. if test -z "${*}"; then
  2952. X  $0 `whoami`;
  2953. fi;
  2954. X
  2955. if test $0 -eq 0; then
  2956. X  printname=false;
  2957. fi;
  2958. X
  2959. return_code=0;
  2960. X
  2961. for named in ${*}; do
  2962. X  last $named | sed -e 's/.*(//g' -e 's/)//g' | awk -F':' \
  2963. X    '{
  2964. X        h += $1; 
  2965. X        m += $2;
  2966. X     }
  2967. X
  2968. X     END { 
  2969. X        while (m >= 60) {
  2970. X          m -= 60;
  2971. X          h++;
  2972. X        }
  2973. X     printf "'$named    '%d:%d\n", h, m;
  2974. X     }'
  2975. X
  2976. done;
  2977. X
  2978. exit $return_code;
  2979. END_OF_FILE
  2980. if test 752 -ne `wc -c <'mitime.d'`; then
  2981.     echo shar: \"'mitime.d'\" unpacked with wrong size!
  2982. fi
  2983. # end of 'mitime.d'
  2984. fi
  2985. if test -f 'mood.1' -a "${1}" != "-c" ; then 
  2986.   echo shar: Will not clobber existing file \"'mood.1'\"
  2987. else
  2988. echo shar: Extracting \"'mood.1'\" \(3509 characters\)
  2989. sed "s/^X//" >'mood.1' <<'END_OF_FILE'
  2990. X.TH mood 1 "2. December 1991"
  2991. X.SH NAME
  2992. mood 0.90 \- get a user's mood
  2993. X.SH SYNOPSIS
  2994. mood [\-m 
  2995. X.I new_mood
  2996. X] [ [\-f] 
  2997. X.I user1 user2 
  2998. X.\|.\|. ] 
  2999. X.SH DESCRIPTION
  3000. X.BR Mood
  3001. prints out the ``mood'' of users in various and sundry formats.  When
  3002. invoked, 
  3003. X.BR mood
  3004. reads the file ~/.mood and prepends 
  3005. X.IR ``user is 
  3006. feeling'' to that file which is then the user's ``mood.'' These are
  3007. the current (supported) options:
  3008. X.TP 10
  3009. X\fB\-f
  3010. gets the moods of all the people in your friends file (see 
  3011. X.BR friends (1))
  3012. X.TP 10
  3013. X\fB\-m
  3014. sets your mood to whatever you type after the flag. Note that control
  3015. characters are ignored, but unlike previous versions of 
  3016. X.BR mood (1), 
  3017. this version prints out the entire file. Formatting will not be
  3018. preserved. 
  3019. X.SH HISTORY
  3020. to take user names from standard input. For each occurrence of `\-' in
  3021. the argument list, standard input is read until 
  3022. X.SM EOF.
  3023. X.SH HISTORY
  3024. Glenn Elliott (whose infamous reputation for horrendous coding style,
  3025. said to be a result of first coding in
  3026. BASIC
  3027. and then converting the results to C, is truly undeserved) wrote the first
  3028. and quite possibly the best version of 
  3029. X.BR mood
  3030. at St. Olaf College in the fall of 1986. Pete TerMaat wrote his version of 
  3031. X.BR mood
  3032. in 1987, his Junior year at St. Olaf in 
  3033. X.BR sh (1)
  3034. and added a few features. In 1987 the 
  3035. X.I moodmail (1) 
  3036. mailing list got started by Pete and was a huge success but in the Fall of
  3037. X1988, since Pete had graduated, Brett M. Rabe and Henry Pierce raced to get
  3038. moodmail up-and-running. Brett was given the source by Pete but it is not
  3039. clear if Henry had gotten the source from tape or written a new version of
  3040. X.BR mood 
  3041. himself. Henry had obtained the user-of-the-day and word-of-the-day as well
  3042. as the moodmail scripts but did not have the actual moodmail program. Brett,
  3043. on the other hand, had the mood program but none of the other stuff. In the
  3044. end, Brett became the new moodmailman. When Brett left St. Olaf in January
  3045. of 1989, Jeff Marker became the new moodmailman although he though that his
  3046. position was temporarly and so he left the program and the sources in
  3047. Brett's
  3048. account.
  3049. X.PP
  3050. During the 90-91 school year, Brett's account was removed, forcing Jeff to
  3051. rewrite the program yet again, this time adding support for 
  3052. X.BR rmood
  3053. and a Sunday edition of the mood mailing list. Also added to the 
  3054. X.BR moodmail (1)
  3055. mailing list were, at various times, quotes from the Bible and the 
  3056. Kama Sutra.
  3057. X
  3058. In the Fall of 1991, Erik Quanstrom rewrote the entire package from scratch,
  3059. deleting many of the old features and adding some of his own, most notably
  3060. direct support for 
  3061. X.IP
  3062. X.BI "mood user@host" 
  3063. X.LP
  3064. remote moods. Erik set up his own mailing list when Jeff's account was
  3065. suspended, not realizing that Jeff Miller was temporarly running moodmail. 
  3066. X
  3067. X.SH BUGS
  3068. X.BR Mood
  3069. requires NIS
  3070. X
  3071. X.B Mood
  3072. will not preserve formatting. To some extent this cannot be
  3073. avoided, but
  3074. X.B Mood 
  3075. should to a better job with this
  3076. X
  3077. X.B Mood
  3078. assumes an 80 column display.
  3079. X.SH "SEE ALSO"
  3080. X.BR moodmail(1), 
  3081. X.BR friends(1),
  3082. X.SH FILES
  3083. X.PD 0
  3084. X.TP 20
  3085. X.B ~/.mood 
  3086. mood file
  3087. X.TP 20
  3088. X.B  ~/.friends
  3089. friends file
  3090. X
  3091. X.SH AUTHOR
  3092. Copyright (C) 1991, 1992 by Erik Quanstrom
  3093. X
  3094. Permission to use, copy, modify, and distribute this software and its
  3095. documentation for any purpose and without fee is hereby granted, provided
  3096. that the above copyright notice appear in all copies and that both that
  3097. copyright notice and this permission notice appear in supporting
  3098. documentation.  This software is provided ``as is'' without express or
  3099. implied warranty.
  3100. END_OF_FILE
  3101. if test 3509 -ne `wc -c <'mood.1'`; then
  3102.     echo shar: \"'mood.1'\" unpacked with wrong size!
  3103. fi
  3104. # end of 'mood.1'
  3105. fi
  3106. if test -f 'mood.d' -a "${1}" != "-c" ; then 
  3107.   echo shar: Will not clobber existing file \"'mood.d'\"
  3108. else
  3109. echo shar: Extracting \"'mood.d'\" \(2787 characters\)
  3110. sed "s/^X//" >'mood.d' <<'END_OF_FILE'
  3111. X#!/bin/sh 
  3112. X#########################################################################
  3113. X# function:    mood 0.90.00                        #
  3114. X#                                    #
  3115. X# object:    print out users moods                    #
  3116. X#                                     #
  3117. X# Erik Quanstrom                            #
  3118. X# 25. Noveber 1991                            #
  3119. X#########################################################################
  3120. h=/usr/local
  3121. PATH=/bin:/usr/bin:/usr/local/bin:/usr/ucb
  3122. X
  3123. if test -z "${*}"; then
  3124. X  $0 `whoami`;
  3125. fi;
  3126. X
  3127. return_code=0;
  3128. X
  3129. for named in ${*};
  3130. X  do
  3131. X    {
  3132. X      shift;
  3133. X      case $named in
  3134. X    -f | -vf | -fv)
  3135. X      $0 -v `cat $HOME/.friends`;;
  3136. X    -m)
  3137. X      cd $HOME;
  3138. X      echo $* > .mood;
  3139. X      chmod a+x .;
  3140. X      chmod a+r ./.mood;
  3141. X      exit 0;;
  3142. X    -v)
  3143. X      FLAG=v;;
  3144. X    -*) 
  3145. X      echo mood: bad argument \"$named\".;
  3146. X      exit 0;;
  3147. X    *@*)
  3148. X          echo $named | awk -F@ '{print $1}' |\
  3149. X        send `echo $named | awk -F@ '{print $2;}'`;;
  3150. X        *)
  3151. X      {
  3152. X        info=`ypmatch $named passwd 2> /dev/null`;
  3153. X      
  3154. X        if test -z "$info" ; then
  3155. X          {
  3156. X                echo "Who the heck is $named anyway?";
  3157. X                return_code=2;
  3158. X              }
  3159. X        else 
  3160. X              {
  3161. X            homedir=`echo $info | awk -F: '{print $6;}'`/.mood;
  3162. X            firstname=`echo $info | awk -F: '
  3163. X            {
  3164. X          for (i=1; i < length($5); i++)
  3165. X            if ((substr($5,i,1) == ",") || (substr($5,i,1) == " "))
  3166. X              {
  3167. X            print substr($5, 1, i-1);
  3168. X            exit;
  3169. X              }
  3170. X
  3171. X          print $5;
  3172. X        }'`
  3173. X          
  3174. X            if test -r $homedir; then 
  3175. X          {
  3176. X           case $FLAG in
  3177. X             *v*)
  3178. X            string="[$named] ";;
  3179. X           esac;
  3180. X                 echo -n "$string$firstname is feeling " |\
  3181. X             cat - $homedir | awk '
  3182. X         {
  3183. X            if (substr($1,1,1) == "[")        
  3184. X              {
  3185. X                verbose=1;
  3186. X            linepos = 11;
  3187. X                saved = sprintf "%s%s", $1, substr("           ",\
  3188. X                1, 11 - length($1) - 1);
  3189. X              }
  3190. X            else
  3191. X              {
  3192. X            saved=$1;
  3193. X            linpos=length($1);
  3194. X              }
  3195. X
  3196. X                    for (i = 2; i <= NF ; i++) 
  3197. X                      {
  3198. X                        if ( ( 2 + linepos + length($i)) >= 79 ) 
  3199. X                          {
  3200. X                            printf "%s\n", saved;
  3201. X                if (verbose != 1)
  3202. X                  {
  3203. X                            saved = "\t";
  3204. X                                linepos=7;
  3205. X                  }
  3206. X                else
  3207. X                 {
  3208. X                    saved = "          ";
  3209. X                linepos=11;
  3210. X                 }
  3211. X                          }
  3212. X                         linepos += length($i);
  3213. X                         saved = sprintf("%s %s", saved, $i);
  3214. X                         linepos++;
  3215. X                       }
  3216. X  
  3217. X                    if (saved != "\t")
  3218. X                      print saved;
  3219. X                  }'
  3220. X        
  3221. X          return_code=0;
  3222. X          }
  3223. X            else 
  3224. X          {
  3225. X              case $FLAG in
  3226. X              *v*)
  3227. X            ;;
  3228. X              *)
  3229. X                echo "$firstname is a stoic dweeb.";;
  3230. X            esac;
  3231. X
  3232. X            return_code=1;
  3233. X          }
  3234. X            fi;
  3235. X        }
  3236. X      fi;
  3237. X        }
  3238. X      esac;
  3239. X    }
  3240. done;
  3241. X
  3242. exit $return_code;
  3243. END_OF_FILE
  3244. if test 2787 -ne `wc -c <'mood.d'`; then
  3245.     echo shar: \"'mood.d'\" unpacked with wrong size!
  3246. fi
  3247. # end of 'mood.d'
  3248. fi
  3249. if test -f 'moodmail.1' -a "${1}" != "-c" ; then 
  3250.   echo shar: Will not clobber existing file \"'moodmail.1'\"
  3251. else
  3252. echo shar: Extracting \"'moodmail.1'\" \(1210 characters\)
  3253. sed "s/^X//" >'moodmail.1' <<'END_OF_FILE'
  3254. X.TH moodmail 1 " 2. December 1991"
  3255. X.SH NAME
  3256. moodmail 0.90 \- a tool for creating mood mailing lists
  3257. X.SH SYNOPSIS
  3258. moodmail [\-e
  3259. X.I expire
  3260. X] [ 
  3261. X.I mailing_list
  3262. X] 
  3263. X.SH DESCRIPTION
  3264. X.B Moodmail 
  3265. compiles a list of recently changed (less than 
  3266. X.I expire
  3267. days old) moods
  3268. and then uses mood to create a file containing the recent moods. This
  3269. file is then sent to all people in the 
  3270. X.I mailing_list 
  3271. file. The default mailing list is located in /usr/local/lib/mooders.
  3272. X
  3273. These are the current (supported) options:
  3274. X.TP 10
  3275. X\fB\-e expire
  3276. set the expire date explicitly. The default is three days. If 
  3277. X.I expire
  3278. is 0, then all moods are reported, regardless of age.
  3279. X
  3280. X.SH BUGS
  3281. None have surfaced, so far.
  3282. X
  3283. X.SH "SEE ALSO"
  3284. X.BR mood (1),
  3285. X.BR friends (1),
  3286. X.BR friends (5)
  3287. X
  3288. X.SH FILES
  3289. X/usr/local/lib/mooders
  3290. X
  3291. X.SH AUTHOR
  3292. Copyright (C) 1991,1992 by Erik Quanstrom
  3293. X
  3294. Permission to use, copy, modify, and distribute this software and its
  3295. documentation for any purpose and without fee is hereby granted, provided
  3296. that the above copyright notice appear in all copies and that both that
  3297. copyright notice and this permission notice appear in supporting
  3298. documentation.  This software is provided "as is" without express or
  3299. implied warranty.
  3300. END_OF_FILE
  3301. if test 1210 -ne `wc -c <'moodmail.1'`; then
  3302.     echo shar: \"'moodmail.1'\" unpacked with wrong size!
  3303. fi
  3304. # end of 'moodmail.1'
  3305. fi
  3306. if test -f 'moodmail.d' -a "${1}" != "-c" ; then 
  3307.   echo shar: Will not clobber existing file \"'moodmail.d'\"
  3308. else
  3309. echo shar: Extracting \"'moodmail.d'\" \(1935 characters\)
  3310. sed "s/^X//" >'moodmail.d' <<'END_OF_FILE'
  3311. X#!/bin/sh
  3312. X#########################################################################
  3313. X# file:         moodmail (0.99.08)                                      #
  3314. X#                                                                       #
  3315. X# object:       do the mood mailing list                                #
  3316. X#                                                                       #
  3317. X#               emphisis on portability _and_ avoiding the cost of an   #
  3318. X#               executable, not on execution speed. This script is      #
  3319. X#               slow, but tolorable when run in the middle of the       #
  3320. X#               night as an at script.                                  #
  3321. X#                                                                       #
  3322. X# files:        $h/lib/moodies          default mailing list            #
  3323. X#               $h/bin/mood             program to do mood              #
  3324. X#               /tmp/mood$$...          mood tmp file                   #
  3325. X#                                                                       #
  3326. X# Erik Quanstrom                                                        #
  3327. X# 10. Januar 1992                                                       #
  3328. X#########################################################################
  3329. h=/home/accserv1/stub/e/quanstro
  3330. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$h/SPARCbin
  3331. X
  3332. mfile=/home/accserv1/stub/e/quanstro/lib/mooders
  3333. X
  3334. case $# in
  3335. X 0 | 1 | 2) : 
  3336. X   ;;
  3337. X *)
  3338. X   echo "usage: $0 [-e expire] [mailing_list]";
  3339. X   exit 1;;
  3340. esac
  3341. X
  3342. while test $# -gt 0; do
  3343. X  case $1 in
  3344. X    -e) if test $# -lt 2; then
  3345. X      echo usage: $0 [-e expire] [mailing_list];
  3346. X      exit 1;
  3347. X    fi
  3348. X    shift;
  3349. X    expire=a"$1";;
  3350. X    -e[0-9] | -e[0-9][0-9] | -e[0-9][0-9][0-9])
  3351. X    expire=a`echo $1 | sed 's/-e//'`;;
  3352. X    *)  if test -f $1; then
  3353. X      mfile=$1;
  3354. X    else
  3355. X      echo "$0: file $1 not found."
  3356. X      exit 1;
  3357. X        fi
  3358. X  esac;
  3359. X  shift;
  3360. done;
  3361. X
  3362. fmood -va"$expire" | Mail -s 'Mood mail' `cat $mfile`;
  3363. exit 0;
  3364. END_OF_FILE
  3365. if test 1935 -ne `wc -c <'moodmail.d'`; then
  3366.     echo shar: \"'moodmail.d'\" unpacked with wrong size!
  3367. fi
  3368. # end of 'moodmail.d'
  3369. fi
  3370. if test -f 'rfriends.d' -a "${1}" != "-c" ; then 
  3371.   echo shar: Will not clobber existing file \"'rfriends.d'\"
  3372. else
  3373. echo shar: Extracting \"'rfriends.d'\" \(908 characters\)
  3374. sed "s/^X//" >'rfriends.d' <<'END_OF_FILE'
  3375. X#!/bin/sh
  3376. X#########################################################################
  3377. X# file:         rfriends                                                #
  3378. X#                                                                       #
  3379. X# object:       are any of my friends on the system?                    #
  3380. X#                                                                       #
  3381. X# Erik Quanstrom                                                        #
  3382. X# 19. Mai 1992                                                          #
  3383. X#########################################################################
  3384. h=/home/accserv1/stub/e/quanstro
  3385. PATH=/bin:/usr/local/bin:$binpath
  3386. X
  3387. X$HOME/SPARCbin/rwho | nawk '
  3388. BEGIN {
  3389. X  x = 0;
  3390. X  while ( 1 == (getline < friends  ) ) {
  3391. X    for (i = 1; i <= NF; i++)
  3392. X    a[$i] = 1;
  3393. X  }
  3394. X  close(friends);
  3395. X}
  3396. X
  3397. X{
  3398. X  if (1 == a[$2] ) {
  3399. X    print $0;
  3400. X    continue;
  3401. X  }
  3402. X}' friends="$HOME"/.friends
  3403. X
  3404. END_OF_FILE
  3405. if test 908 -ne `wc -c <'rfriends.d'`; then
  3406.     echo shar: \"'rfriends.d'\" unpacked with wrong size!
  3407. fi
  3408. # end of 'rfriends.d'
  3409. fi
  3410. if test -f 'rw.1' -a "${1}" != "-c" ; then 
  3411.   echo shar: Will not clobber existing file \"'rw.1'\"
  3412. else
  3413. echo shar: Extracting \"'rw.1'\" \(1180 characters\)
  3414. sed "s/^X//" >'rw.1' <<'END_OF_FILE'
  3415. X.TH rw 1 "14. January 1992"
  3416. X.SH NAME
  3417. rw 0.90 \- reports on remote users 
  3418. X.IR tersly .
  3419. X.SH SYNOPSIS
  3420. rw [
  3421. X.I server 
  3422. X] [
  3423. X.I port
  3424. X]
  3425. X.SH DESCRIPTION
  3426. X.B Rw
  3427. connects to the server on the commmand line, or if no server is
  3428. given, the default server which is compiled in at make-time to find
  3429. out who's logged in.
  3430. X.B Rw
  3431. reports the first 16 characters of the machine name in square
  3432. brackets, then lists the users who are logged into that machine. Lines
  3433. are wrapped to eighty columns to make the output more readable.
  3434. X.SH BUGS
  3435. X.B Rw
  3436. assumes an 80 column display.
  3437. X
  3438. X.SH "SEE ALSO" 
  3439. X.BR friends (1), 
  3440. X.BR friends (5), 
  3441. X.BR fmood (1),
  3442. X.BR moodmail (1), 
  3443. X.BR mood (1), 
  3444. X.BR rw (1)
  3445. X
  3446. X.SH FILES
  3447. X.PD 0
  3448. X.TP 20
  3449. X.B ~/.friends
  3450. friends file
  3451. X.TP
  3452. X.B /etc/utmp
  3453. who is logged in
  3454. X.PD
  3455. X.SH AUTHOR
  3456. Copyright (C) 1991, 1992 by Erik Quanstrom
  3457. X
  3458. Permission to use, copy, modify, and distribute this software and its
  3459. documentation for any purpose and without fee is hereby granted, provided
  3460. that the above copyright notice appear in all copies and that both that
  3461. copyright notice and this permission notice appear in supporting
  3462. documentation.  This software is provided ``as is'' without express or
  3463. implied warranty.
  3464. X
  3465. END_OF_FILE
  3466. if test 1180 -ne `wc -c <'rw.1'`; then
  3467.     echo shar: \"'rw.1'\" unpacked with wrong size!
  3468. fi
  3469. # end of 'rw.1'
  3470. fi
  3471. if test -f 'rw.d' -a "${1}" != "-c" ; then 
  3472.   echo shar: Will not clobber existing file \"'rw.d'\"
  3473. else
  3474. echo shar: Extracting \"'rw.d'\" \(981 characters\)
  3475. sed "s/^X//" >'rw.d' <<'END_OF_FILE'
  3476. X#!/bin/sh
  3477. X#########################################################################
  3478. X# file:        rw                            #
  3479. X#                                    #
  3480. X# object:    put rwho (1) output into a shorter format        #
  3481. X#                                    #
  3482. X# Copyright (C) 1992 Erik Quanstrom                    #
  3483. X#                                    #
  3484. X# 22. Mai 1992                                #
  3485. X#########################################################################
  3486. h=/home/accserv1/stub/e/quanstro
  3487. PATH=$h/SPARCbin:/bin:/usr/bin:/usr/ucb/bin
  3488. X
  3489. rwho $* | awk '
  3490. X
  3491. BEGIN { old = ""; }
  3492. X
  3493. X{
  3494. X  if ($1 != old)
  3495. X    {
  3496. X      if (old != "")
  3497. X    printf "\n";
  3498. X
  3499. X      printf "%s %s ", $1, $2;
  3500. X    }
  3501. X  else
  3502. X    {
  3503. X      printf "%s ", $2;
  3504. X    }
  3505. X
  3506. X  old = $1;
  3507. X}' | awk '
  3508. X{
  3509. X  linepos = length($1);
  3510. X  saved = sprintf("%s", $1);
  3511. X  
  3512. X  for (i = 2; i <= NF ; i++) 
  3513. X    {
  3514. X      if ( ( 1 + linepos + length($i)) > 79 ) 
  3515. X    {
  3516. X      printf "%s\n", saved;
  3517. X      saved = "                 ";
  3518. X      linepos=17;
  3519. X    }
  3520. X
  3521. X      linepos += length($i);
  3522. X      saved = sprintf("%s %s", saved, $i);
  3523. X      linepos++;
  3524. X    }
  3525. X  
  3526. X  if (saved != "\t")
  3527. X    print saved;
  3528. X}'
  3529. X
  3530. X  
  3531. X
  3532. X
  3533. END_OF_FILE
  3534. if test 981 -ne `wc -c <'rw.d'`; then
  3535.     echo shar: \"'rw.d'\" unpacked with wrong size!
  3536. fi
  3537. # end of 'rw.d'
  3538. fi
  3539. if test -f 'rwho.1' -a "${1}" != "-c" ; then 
  3540.   echo shar: Will not clobber existing file \"'rwho.1'\"
  3541. else
  3542. echo shar: Extracting \"'rwho.1'\" \(1225 characters\)
  3543. sed "s/^X//" >'rwho.1' <<'END_OF_FILE'
  3544. X.TH rwho 1 "14. January 1992"
  3545. X.SH NAME
  3546. rwho 0.90 \- reports on remote users
  3547. X.SH SYNOPSIS
  3548. rwho [
  3549. X.IR server ] 
  3550. X[
  3551. X.I port
  3552. X]
  3553. X.SH DESCRIPTION
  3554. X.B Rwho
  3555. connects to the server on the commmand line, or if no server is
  3556. given, the default server which is compiled in at make-time to find
  3557. out who's logged in.
  3558. X.B Rwho 
  3559. reports the first 16 characters of the machine name in square
  3560. brackets, then the user name, the terminal and finally, in round
  3561. brackets, the machine from which the user has logged in.
  3562. X.SH BUGS
  3563. Haven't found any yet.
  3564. X
  3565. X.SH "SEE ALSO" 
  3566. X.BR friends (1), 
  3567. X.BR friends (5), 
  3568. X.BR moodmail (1), 
  3569. X.BR mood (1), 
  3570. X.BR fmood (1),
  3571. X.BR rw (1)
  3572. X.SH files
  3573. X.PD 0
  3574. X.TP 20
  3575. X.B ~/.friends
  3576. friends file
  3577. X.TP
  3578. X.B /etc/utmp
  3579. who is logged in
  3580. X.TP
  3581. X.B /etc/passwd
  3582. for users' names
  3583. X.TP
  3584. X.B /etc/ttytab
  3585. terminal locations
  3586. X.PD
  3587. X.SH AUTHOR
  3588. Copyright (C) 1991, 1992 by Erik Quanstrom
  3589. X
  3590. Permission to use, copy, modify, and distribute this software and its
  3591. documentation for any purpose and without fee is hereby granted, provided
  3592. that the above copyright notice appear in all copies and that both that
  3593. copyright notice and this permission notice appear in supporting
  3594. documentation.  This software is provided ``as is'' without express or
  3595. implied warranty.
  3596. X
  3597. END_OF_FILE
  3598. if test 1225 -ne `wc -c <'rwho.1'`; then
  3599.     echo shar: \"'rwho.1'\" unpacked with wrong size!
  3600. fi
  3601. # end of 'rwho.1'
  3602. fi
  3603. if test -f 'rwho.c' -a "${1}" != "-c" ; then 
  3604.   echo shar: Will not clobber existing file \"'rwho.c'\"
  3605. else
  3606. echo shar: Extracting \"'rwho.c'\" \(2087 characters\)
  3607. sed "s/^X//" >'rwho.c' <<'END_OF_FILE'
  3608. X/************************************************************************
  3609. X * file:        rwho.c                            *
  3610. X *                                     *
  3611. X * Object:    talk to the rwho server and get info            *
  3612. X *                                     *
  3613. X * Copyright (C) Erik Quanstrom, 1992                    *
  3614. X *                                    *
  3615. X * Erik Quanstrom                            *
  3616. X * 23. Januar 1992                            *
  3617. X ************************************************************************/
  3618. X#define DEFAULT_PORT 5002
  3619. X
  3620. X#include <stdio.h>
  3621. X#include <sys/types.h>
  3622. X#include <sys/file.h>
  3623. X#include <sys/socket.h>
  3624. X#include <netdb.h>
  3625. X#include <netinet/in.h>
  3626. X
  3627. X#define INFO_REQUESTs "*"
  3628. X
  3629. typedef struct sockaddr SOCK;
  3630. typedef struct sockaddr_in SOCK_IN;
  3631. X
  3632. void die(int status);
  3633. char *program;
  3634. X
  3635. X#ifndef SERVER
  3636. X#define SERVER "mari.acc.stolaf.edu"
  3637. X#endif
  3638. X
  3639. X/************************************************************************
  3640. X * function:    main()                            *
  3641. X *                                     *
  3642. X * object:    get info from the rwho daemon on the server        *
  3643. X *                                     *
  3644. X * Erik Quanstrom                             *
  3645. X * 23. Januar 1992                            *
  3646. X ************************************************************************/
  3647. int main ( int argc, char **argv, char **envp) 
  3648. X{
  3649. X  struct hostent *hp;
  3650. X  SOCK_IN *sin = (SOCK_IN *)malloc(sizeof(SOCK_IN));
  3651. X  int s,
  3652. X      c;
  3653. X
  3654. X  FILE *f;
  3655. X  
  3656. X  program = *argv;
  3657. X  
  3658. X  if (argc > 3 )
  3659. X    {
  3660. X      printf("usage: %s hostname [port-number]\n", *argv);
  3661. X      exit (1);
  3662. X    }
  3663. X  
  3664. X  if (!argv[1])
  3665. X    argv[1] = SERVER;
  3666. X  
  3667. X  if ( (sin->sin_addr.s_addr = inet_addr( argv[1] )) != -1)
  3668. X    sin->sin_family = AF_INET;
  3669. X  else
  3670. X    if (hp = gethostbyname(argv[1])) 
  3671. X      {
  3672. X    sin->sin_family = hp->h_addrtype;
  3673. X    bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
  3674. X      } 
  3675. X    else 
  3676. X      die(1);
  3677. X  
  3678. X  if ( argc > 2 )
  3679. X    sin->sin_port = htons( atoi(argv[2]));
  3680. X  else
  3681. X    sin->sin_port = htons( (int)DEFAULT_PORT );
  3682. X  
  3683. X  
  3684. X  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
  3685. X    die(1);
  3686. X
  3687. X  if (connect(s, sin, sizeof(SOCK_IN)) < 0)
  3688. X    die(1);
  3689. X
  3690. X  write(s, INFO_REQUESTs, 1);
  3691. X      
  3692. X  if (!(f = fdopen(s, "r")))
  3693. X    die(1);
  3694. X  
  3695. X  while((c = getc(f)) != EOF)
  3696. X    putc(c, stdout);
  3697. X
  3698. X  return 0;
  3699. X}
  3700. X         
  3701. void die(int status)
  3702. X{
  3703. X  perror( program );
  3704. X  exit (status);
  3705. X}
  3706. END_OF_FILE
  3707. if test 2087 -ne `wc -c <'rwho.c'`; then
  3708.     echo shar: \"'rwho.c'\" unpacked with wrong size!
  3709. fi
  3710. # end of 'rwho.c'
  3711. fi
  3712. if test -f 'theirmail.1' -a "${1}" != "-c" ; then 
  3713.   echo shar: Will not clobber existing file \"'theirmail.1'\"
  3714. else
  3715. echo shar: Extracting \"'theirmail.1'\" \(1126 characters\)
  3716. sed "s/^X//" >'theirmail.1' <<'END_OF_FILE'
  3717. X.TH theirmail 1 " 17. January 1992"
  3718. X.SH NAME
  3719. theirmail 0.90 \- reports on other user's mail
  3720. X.SH SYNOPSIS
  3721. theirmail [-s
  3722. X.IR spool_dir ]
  3723. X.I user1 
  3724. X.IR user2 .\|.\|.
  3725. X.SH DESCRIPTION
  3726. XFor each user in its argument list, 
  3727. X.B theirmail
  3728. displays either
  3729. X.IP
  3730. X.BI "no mail for <" user ">
  3731. X.LP
  3732. or, if the user's mailbox has a positive size, 
  3733. X.IP
  3734. X.BI "<" user "> has mail (last recieved: <" date "> )"
  3735. X.LP
  3736. If the \-s flag is given, then 
  3737. X.I spool_dir 
  3738. is used instead of the default (usually /usr/spool/mail). 
  3739. X.SH BUGS
  3740. X.B Theirmail 
  3741. is too slow.
  3742. X.SH "SEE ALSO"
  3743. X.BR mood (1),
  3744. X.BR moodmail (1),
  3745. X.BR fmood (1),
  3746. X.BR ffriends (1),
  3747. X.BR friends (5),
  3748. X.BR geeks (1)
  3749. X
  3750. X.SH FILES
  3751. X.PD 0
  3752. X.TP 20
  3753. X.B /usr/spool/mail/*
  3754. mail files
  3755. X
  3756. X.SH AUTHOR
  3757. Copyright (C) 1991, 1992 by Erik Quanstrom
  3758. X
  3759. Permission to use, copy, modify, and distribute this software and its
  3760. documentation for any purpose and without fee is hereby granted, provided
  3761. that the above copyright notice appear in all copies and that both that
  3762. copyright notice and this permission notice appear in supporting
  3763. documentation.  This software is provided ``as is'' without express or
  3764. implied warranty.
  3765. END_OF_FILE
  3766. if test 1126 -ne `wc -c <'theirmail.1'`; then
  3767.     echo shar: \"'theirmail.1'\" unpacked with wrong size!
  3768. fi
  3769. # end of 'theirmail.1'
  3770. fi
  3771. if test -f 'theirmail.d' -a "${1}" != "-c" ; then 
  3772.   echo shar: Will not clobber existing file \"'theirmail.d'\"
  3773. else
  3774. echo shar: Extracting \"'theirmail.d'\" \(1355 characters\)
  3775. sed "s/^X//" >'theirmail.d' <<'END_OF_FILE'
  3776. X#!/bin/sh
  3777. X#########################################################################
  3778. X#                             Theirmail                                 #
  3779. X#                    Produces one line of output                        #
  3780. X#                    for each argument (logname)                        #
  3781. X#            Assumes that no arg =                #
  3782. X#                your log name                #
  3783. X#                                    #
  3784. X#                       Erik Walter Quanstrom,                          #
  3785. X#                         Jeffrey S. Marker                             #
  3786. X#                           Brett M. Rabe                               #
  3787. X#########################################################################
  3788. X#version 1.03
  3789. h=/usr/spool/mail
  3790. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$h/SPARCbin
  3791. status=0;
  3792. X
  3793. case $1 in
  3794. X  -s) shift;
  3795. X      if test -z "${*}"; then
  3796. X        echo "usage: $0 [-s spool_dir] user1 user2 ..."
  3797. X        exit 1;
  3798. X      fi   
  3799. X   
  3800. X      h=$1;
  3801. X      if test '!' -d $h; then
  3802. X        echo "$0: $h is not a directory."
  3803. X        exit 1;
  3804. X      fi;
  3805. X
  3806. X      shift;;
  3807. esac;
  3808. X
  3809. if test -z "${*}"; then
  3810. X  $0 `whoami`;
  3811. X else
  3812. X  for user in ${*}; do
  3813. X    if test -s "$h"/"${user}"; then
  3814. X      echo -n "${user} has mail (last recieved: ";
  3815. X      ls -l "$h"/"${user}" |\
  3816. X    awk '{print $5" "$6" "$7")"}';
  3817. X    else
  3818. X      echo "no mail for ${user}."
  3819. X      status=1;
  3820. X    fi;
  3821. X  done;
  3822. fi;
  3823. X
  3824. exit $status;
  3825. END_OF_FILE
  3826. if test 1355 -ne `wc -c <'theirmail.d'`; then
  3827.     echo shar: \"'theirmail.d'\" unpacked with wrong size!
  3828. fi
  3829. # end of 'theirmail.d'
  3830. fi
  3831. echo shar: End of archive 1 \(of 1\).
  3832. cp /dev/null ark1isdone
  3833. MISSING=""
  3834. for I in 1 ; do
  3835.     if test ! -f ark${I}isdone ; then
  3836.     MISSING="${MISSING} ${I}"
  3837.     fi
  3838. done
  3839. if test "${MISSING}" = "" ; then
  3840.     echo You have the archive.
  3841.     rm -f ark[1-9]isdone
  3842. else
  3843.     echo You still need to unpack the following archives:
  3844.     echo "        " ${MISSING}
  3845. fi
  3846. ##  End of shell archive.
  3847. exit 0
  3848.