home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume36 / msend / part02 < prev    next >
Encoding:
Text File  |  1993-03-21  |  36.9 KB  |  1,298 lines

  1. Newsgroups: comp.sources.misc
  2. From: spike@world.std.com (Joe Ilacqua)
  3. Subject: v36i019:  msend - a write/wall/rwall/talk replacement, v1.2, Part02/02
  4. Message-ID: <1993Mar19.193321.1830@sparky.imd.sterling.com>
  5. X-Md4-Signature: 298bd413929526a53429679941507436
  6. Date: Fri, 19 Mar 1993 19:33:21 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: spike@world.std.com (Joe Ilacqua)
  10. Posting-number: Volume 36, Issue 19
  11. Archive-name: msend/part02
  12. Environment: UNIX, networking
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  Copyright History Makefile config.h domessage.c
  19. #   establish.c fwdloop.c gnugets.c msend.h msend.man msendd.c
  20. #   network.h patchlevel utmp.c whoami.c
  21. # Wrapped by kent@sparky on Fri Mar 19 13:24:30 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 2 (of 2)."'
  25. if test -f 'Copyright' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'Copyright'\"
  27. else
  28.   echo shar: Extracting \"'Copyright'\" \(1136 characters\)
  29.   sed "s/^X//" >'Copyright' <<'END_OF_FILE'
  30. X#ifndef _COPYRIGHT_
  31. X/* (c) Copyright 1988, 1989, 1990, 1991 Jim Frost
  32. X * All Rights Reserved
  33. X *
  34. X * Permission to use, copy, modify, distribute, and sell this software
  35. X * and its documentation for any purpose is hereby granted without fee,
  36. X * provided that the above copyright notice appear in all copies and
  37. X * that both that copyright notice and this permission notice appear
  38. X * in supporting documentation.  The author makes no representations
  39. X * about the suitability of this software for any purpose.  It is
  40. X * provided "as is" without express or implied warranty.
  41. X *
  42. X * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  43. X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
  44. X * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  45. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  46. X * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  47. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
  48. X * USE OR PERFORMANCE OF THIS SOFTWARE.
  49. X */
  50. X
  51. Xstatic char *Copyright= "Copyright 1988, 1989, 1990, 1991 Jim Frost";
  52. X#define _COPYRIGHT_
  53. X#endif
  54. END_OF_FILE
  55.   if test 1136 -ne `wc -c <'Copyright'`; then
  56.     echo shar: \"'Copyright'\" unpacked with wrong size!
  57.   fi
  58.   # end of 'Copyright'
  59. fi
  60. if test -f 'History' -a "${1}" != "-c" ; then 
  61.   echo shar: Will not clobber existing file \"'History'\"
  62. else
  63.   echo shar: Extracting \"'History'\" \(1833 characters\)
  64.   sed "s/^X//" >'History' <<'END_OF_FILE'
  65. X5.16.88  Original version
  66. X5.18.88  Add forward loop checking to sendmsg() and add -clean option to
  67. X         msend.
  68. X5.21.88  Break up application, packet, and network sections in a
  69. X         cleaner manner.  Add the ability to maintain a connection for
  70. X         more than one message.  Add uid managing to keep root
  71. X         uid-ness for only short periods of time and to properly
  72. X         handle files from the daemon.
  73. X5.22.88  Fix ndbm bug in home.c.  Fix setuid bug in sendrecv.c.  Add
  74. X         code segment to msend.c to open connection before going
  75. X         interactive.
  76. X2.7.90   Fix bug in SIGCHLD handler in msendd.c.  If wait3 returned
  77. X         zero the daemon would infinite loop.  Add TIOCNOTTY ioctl to
  78. X         disassociate daemon from tty.
  79. X6.4.90   Fix bug in daemon where setgid was called with only one argument.
  80. X10.12.90 Added code to support use of the GNU readline package for
  81. X         input line editing. ->Spike
  82. X10.15.90 Remove domain name for signature after first message is sent.
  83. X         For the poor folks at slopoke.mbl.semi.harris.com.  Fix host
  84. X         connection to use h_errno, and fake h_errno/h_errlist on
  85. X         systems that lack it. ->Spike
  86. X5.7.91   Fixed bug that caused random behavor on routed messages.
  87. X         Cleaned up readline support.  Rearranged source a bit and
  88. X         added prototypes.  Makefile overhauled.  Miscellaneous SYSV
  89. X         fixes for the SGI. ->Spike
  90. X5.9.91   Slightly better SysV/POSIX support.  Other misc. cleanups.
  91. X5.9.91   Support for hosts with multiple IP addresses and for using IP
  92. X         addresses instead of hostnames. ->Spike
  93. X6.26.91  Ported to HP-UX. ->Spike
  94. X9.4.91   Add secure port code. ->Spike
  95. X12.11.91 Cleanup for release after 3 years. ->Spike
  96. X3.5.91   Minor security fix and SCO UNIX-ODT port from Chris Riney
  97. X         (chris@tisdec.tis.tandy.com).
  98. END_OF_FILE
  99.   if test 1833 -ne `wc -c <'History'`; then
  100.     echo shar: \"'History'\" unpacked with wrong size!
  101.   fi
  102.   # end of 'History'
  103. fi
  104. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  105.   echo shar: Will not clobber existing file \"'Makefile'\"
  106. else
  107.   echo shar: Extracting \"'Makefile'\" \(3393 characters\)
  108.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  109. X# (c) Copyright 1988 Jim Frost.  All Rights Reserved.  Please see
  110. X# the accompanying file "Copyright" for more information.
  111. X#
  112. X# Be sure to read "Configuration" and make necessary changes to "config.h"
  113. X# before compiling.
  114. X
  115. X# Send bugs, fixes, and ports to 'msend-bugs@world.std.com'.
  116. X
  117. X# DESTDIR is the directory to install msend in.
  118. XDESTDIR = /usr/local/bin
  119. X
  120. X# DAEMONDIR is the directory to install the msend daemon in.
  121. XDAEMONDIR = /usr/etc
  122. X
  123. X# DAEMONNAME is what to call the daemon.  Sun likes "in.msendd", others may
  124. X# prefer "msendd".
  125. XDAEMONNAME = in.msendd
  126. X#DAEMONNAME = msendd
  127. X
  128. X# MANDIR is the directory to install the man page in
  129. XMANDIR = /usr/man/manl
  130. X# MANSEC is the section the man page is to be installed it.
  131. XMANSEC = l
  132. X
  133. X# SPOOLDIR should be the same as the #define in config.h
  134. XSPOOLDIR = /usr/spool/msend
  135. X
  136. XCFLAGS = -O
  137. X
  138. X# Under SUNOS you may need "-lresolv" see Configuration
  139. X#LIBS = -lresolv
  140. X# Under IRIX  you may need "-lsun -lbsd" see Configuration
  141. X#LIBS = -lsun -lbsd
  142. X# Under SCO UNIX-ODT you will need: -lx -lsocket
  143. X#LIBS= -lx -lsocket
  144. X
  145. X#READLINELIBS = -lreadline -ltermcap
  146. X
  147. X# It is unlikely you will need to change anything bellow.
  148. X
  149. X# grrr
  150. XSHELL = /bin/sh
  151. X
  152. XMISC = Configuration Copyright History Makefile patchlevel Protocol README \
  153. X       msend.man msend.h network.h config.h
  154. XSRCS = domessage.c establish.c fwdloop.c gnugets.c misc.c msend.c \
  155. X       msendd.c network.c sendrecv.c utmp.c whoami.c write.c
  156. XALL = $(MISC) $(SRCS)
  157. X
  158. XDSRCS = domessage.c establish.c fwdloop.c misc.c network.c msendd.c \
  159. X        sendrecv.c utmp.c write.c 
  160. XCSRCS = gnugets.c misc.c msend.c network.c sendrecv.c whoami.c
  161. XDOBJS = domessage.o establish.o fwdloop.o misc.o network.o msendd.o \
  162. X        sendrecv.o utmp.o write.o 
  163. XCOBJS = gnugets.o misc.o msend.o network.o sendrecv.o whoami.o
  164. X
  165. Xall: msend msendd
  166. X
  167. X
  168. Xmsend: $(COBJS)
  169. X    $(CC) $(CFLAGS) $(COBJS) -o msend $(LIBS) $(READLINELIBS)
  170. X
  171. Xmsendd:  $(DOBJS)
  172. X    $(CC) $(CFLAGS) $(DOBJS) -o msendd $(LIBS)
  173. X
  174. Xinstall: msend msendd
  175. X    install -c -s -m 6555 -g tty msend $(DESTDIR)
  176. X    install -c -s -m 2555 -g tty msendd $(DAEMONDIR)/$(DAEMONNAME)
  177. X    install -c -m 444 msend.man $(MANDIR)/msend.$(MANSEC)
  178. X    if [ ! -d $(SPOOLDIR) ]; then \
  179. X     mkdir $(SPOOLDIR); \
  180. X     chmod 2771 $(SPOOLDIR); \
  181. X     chgrp tty $(SPOOLDIR); \
  182. X    fi
  183. X
  184. Xinstall-sysv: msend msendd
  185. X    strip msend msendd
  186. X    cp msend $(DESTDIR)
  187. X    cp msendd $(DAEMONDIR)/$(DAEMONNAME)
  188. X    chgrp tty $(DESTDIR)/msend $(DAEMONDIR)/$(DAEMONNAME)
  189. X    chmod 6555 $(DESTDIR)/msend
  190. X    chmod 2555 $(DAEMONDIR)/$(DAEMONNAME)
  191. X    cp msend.man $(MANDIR)/msend.$(MANSEC)
  192. X    chmod 444 $(MANDIR)/msend.$(MANSEC)
  193. X    if [ ! -d $(SPOOLDIR) ]; then \
  194. X     mkdir $(SPOOLDIR); \
  195. X     chmod 2771 $(SPOOLDIR); \
  196. X     chgrp tty $(SPOOLDIR); \
  197. X    fi
  198. X
  199. Xshar: 
  200. X    rm -f shar.*
  201. X    shar -l 60 -o shar $(ALL)
  202. X
  203. Xmsend.tar:
  204. X    tar cf msend.tar $(ALL)
  205. X
  206. Xtar: msend.tar
  207. X
  208. Xtar.Z: msend.tar
  209. X    compress msend.tar
  210. X
  211. Xsrcinsaber:: $(DSRCS)
  212. X    #load $(DSRCS)
  213. X
  214. Xsrcinsaber:: $(CSRCS)
  215. X    #load $(CSRCS)
  216. X
  217. Xclean:
  218. X    rm -f *.o *~ shar.* doshar msend msendd buildshar msend.tar msend.tar.Z
  219. X
  220. Xdomessage.o:  msend.h network.h config.h patchlevel
  221. Xestablish.o: msend.h network.h
  222. Xfwdloop.o: msend.h network.h
  223. Xgnugets.o: config.h
  224. Xmisc.o: msend.h network.h config.h
  225. Xmsend.o: msend.h network.h config.h Copyright patchlevel
  226. Xmsendd.o: msend.h network.h config.h
  227. Xnetwork.o: msend.h network.h config.h
  228. Xsendrecv.o: msend.h network.h config.h
  229. Xutmp.o: msend.h network.h
  230. Xwhoami.o: msend.h network.h
  231. Xwrite.o: msend.h network.h config.h
  232. END_OF_FILE
  233.   if test 3393 -ne `wc -c <'Makefile'`; then
  234.     echo shar: \"'Makefile'\" unpacked with wrong size!
  235.   fi
  236.   # end of 'Makefile'
  237. fi
  238. if test -f 'config.h' -a "${1}" != "-c" ; then 
  239.   echo shar: Will not clobber existing file \"'config.h'\"
  240. else
  241.   echo shar: Extracting \"'config.h'\" \(2665 characters\)
  242.   sed "s/^X//" >'config.h' <<'END_OF_FILE'
  243. X/* config.h:
  244. X *
  245. X * configuration file for 'msend'
  246. X *
  247. X * (c) Copyright 1991 Jim Frost.  All Rights Reserved.  Please see
  248. X * the accompanying file "Copyright" for more information.
  249. X */
  250. X
  251. X#define ON 1
  252. X#define OFF 0
  253. X
  254. X/* system dependencies and options
  255. X */
  256. X
  257. X#define PORTNUM      56060   /* port number that we use.  should be under
  258. X                               1024 for installed versions to make sure
  259. X                               we're getting real data.  note that an
  260. X                               /etc/services entry overrides this */
  261. X
  262. X#define DBROADCAST    /* allow broadcasting at daemon host */
  263. X#define CBROADCAST    /* allow broadcasting from user interface */
  264. X#define ROUTE         /* allow message routing at daemon host */
  265. X#define SECURE_PORT   /* connect from a secure port to allow authentication */
  266. X/* #define GNUREADLINE   /* use GNU readline for the user interface. */
  267. X/* #define EDIT OFF      /* should gnureadline editing be ON/OFF by default */
  268. X/* #define ALONE      /* not running under inetd - build standalone daemon */
  269. X
  270. X/* this is the name of the log file msend will use.  /usr/adm/msend.log is
  271. X * usually good.
  272. X */
  273. X#define LOGFILE     "/usr/adm/msend.log"
  274. X
  275. X/* if you would rather have the spool files in individual users' directories,
  276. X * comment this line out.
  277. X */
  278. X#define SPOOLDIR    "/usr/spool/msend"
  279. X
  280. X/* a few common systems' definitions
  281. X */
  282. X#ifdef sun
  283. X/* nothing special about a Sun */
  284. X#endif
  285. X
  286. X#ifdef _AIX
  287. X#define USE_LOCKF
  288. X#define SYSV_WAIT_STATUS
  289. X#endif
  290. X
  291. X#if defined(sgi) && defined(mips)
  292. X#define SYSVUTMP
  293. X#endif
  294. X
  295. X#ifdef M_SYSV
  296. X#define SYSVUTMP
  297. X#define SYSV_WAIT_STATUS
  298. X#define SYSV_SETUID
  299. X#define NO_BZERO
  300. X#endif
  301. X
  302. X/* system-dependent definitions
  303. X */
  304. X/* #define USE_LOCKF  /* Use lockf() instead of flock() */
  305. X/* #define NEEDS_LOCK /* OS lacks both flock() and locfk() */
  306. X/* #define SYSVUTMP   /* system uses SYSV style utmp file */
  307. X/* #define NOHERROR  /* systems libraries do not contain h_errno. */
  308. X/* #define SYSV_WAIT_STATUS /* wait status is int not union */
  309. X/* #define SYSV_SETUID /* if your system uses SYSV setuid semantics*/
  310. X/* #define NO_BZERO  /* to use mem{set,copy}() instead of b{zero,copy}() */
  311. X
  312. X#ifdef SYSV_SETUID
  313. X#define seteuid(uid) setuid(uid) /* If OS lacks seteuid(2) and setruid(2) */
  314. X#define setruid(uid) 0 /* and has SYSV setuid(2) semantics */
  315. X#endif
  316. X
  317. X/* BSD systems define wait status as a union, while SYSV as an int.
  318. X */
  319. X#ifdef SYSV_WAIT_STATUS
  320. X#define WAIT_STATUS int        /* SYSV-style wait status */
  321. X#else
  322. X#define WAIT_STATUS union wait /* BSD-style wait status */
  323. X#endif
  324. X
  325. X#ifdef NO_BZERO
  326. X#define bzero(address,size) memset(address, '\0', size)
  327. X#define bcopy(b1,b2,lenght) memcopy(b2,b1,lenght)
  328. X#endif
  329. END_OF_FILE
  330.   if test 2665 -ne `wc -c <'config.h'`; then
  331.     echo shar: \"'config.h'\" unpacked with wrong size!
  332.   fi
  333.   # end of 'config.h'
  334. fi
  335. if test -f 'domessage.c' -a "${1}" != "-c" ; then 
  336.   echo shar: Will not clobber existing file \"'domessage.c'\"
  337. else
  338.   echo shar: Extracting \"'domessage.c'\" \(3606 characters\)
  339.   sed "s/^X//" >'domessage.c' <<'END_OF_FILE'
  340. X/* domessage.c:
  341. X *
  342. X * this handles each incoming message
  343. X *
  344. X * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  345. X * the accompanying file "Copyright" for more information.
  346. X */
  347. X
  348. X#include "Copyright"
  349. X#include "config.h"
  350. X#include "msend.h"
  351. X#include "patchlevel"
  352. X
  353. Xextern char *sys_errlist[];
  354. Xextern int  errno;
  355. Xextern short doroute, dobroadcast;
  356. X
  357. X/* in case we somehow get caught in an inconsistent state, we
  358. X * kill ourselves after an arbitrary time.
  359. X */
  360. X
  361. Xstatic void suicide()
  362. X{ error("child killed after lifetime expired");
  363. X  die(1);
  364. X}
  365. X
  366. X/* handle the incoming message
  367. X */
  368. X
  369. Xvoid domessage(s)
  370. Xint s;
  371. X{ struct simsg   si;
  372. X  struct rimsg   ri;
  373. X  extern int     errno;
  374. X  char   localhost[MAXHOSTNAME+1];
  375. X  char   tmphost[MAXHOSTNAME+1];
  376. X  struct hostent *hp;
  377. X
  378. X  for (;;) {
  379. X
  380. X    /* anything we say can and will be used against us in the court of
  381. X     * law, so it's a good idea to keep our mouth shut except with the
  382. X     * right people.  In other words, nobody but root and the owner
  383. X     * should be able to see message files.
  384. X     */
  385. X
  386. X    umask(006);
  387. X
  388. X    /* this is our guarantee that we won't have processes sitting in
  389. X     * funny states for very long.  unfortunately it can also cause
  390. X     * valid connections to die if the user ignores them for long
  391. X     * enough, but we reset the timer every time there's a packet.
  392. X     */
  393. X
  394. X    alarm(LIFETIME);
  395. X    signal(SIGALRM,suicide);
  396. X
  397. X    gethostname(tmphost,MAXHOSTNAME);
  398. X    if ((hp = gethostbyname(tmphost)) == NULL);
  399. X    (void) strncpy(localhost,hp->h_name,MAXHOSTNAME);
  400. X    
  401. X
  402. X    /* hello?  what do you want? */
  403. X
  404. X    recvmessage(s,&si);
  405. X
  406. X    /* look to see if we are supposed to route this to somewhere.  if so,
  407. X     * then do it.
  408. X     */
  409. X
  410. X    if (striphost(si.taddr,si.tohost) != NULL) {
  411. X#ifdef ROUTE
  412. X      if(doroute)
  413. X    sendmessage(&si,&ri,si.mode); /* route the message and get reply */
  414. X
  415. X      /* routing is disabled so return an error message
  416. X       */
  417. X      else {
  418. X#endif
  419. X    ri.h.errno= RE_NOROUTE;
  420. X    sprintf(ri.msg,"%s: Message routing is disabled at this host",localhost);
  421. X#ifdef ROUTE
  422. X      }
  423. X#endif
  424. X    }
  425. X    else if (si.mode & SM_VERSION) {
  426. X      ri.h.errno= RE_OK;
  427. X      sprintf(ri.msg,"%s: msendd version %s patchlevel %s  %s",
  428. X          localhost,VERSION,PATCHLEVEL,Copyright);
  429. X    }
  430. X    else if (si.msg[0] == '\0') { /* null messages are ignored */
  431. X      ri.h.errno= RE_OK;
  432. X      ri.msg[0]= '\0';
  433. X    }
  434. X
  435. X    else if (si.mode & SM_BROADCAST) {
  436. X
  437. X#ifdef DBROADCAST
  438. X      /* broadcast to everyone in utmp
  439. X       */
  440. X
  441. X      if (dobroadcast) {
  442. X    broadcast(&si);
  443. X    ri.h.errno= RE_OK;
  444. X    ri.msg[0]= '\0';
  445. X      } else {
  446. X#endif
  447. X    ri.h.errno= RE_NOBROAD;
  448. X    sprintf(ri.msg,"%s: Broadcasting is disabled at this host",localhost);
  449. X#ifdef DBROADCAST
  450. X      }
  451. X#endif
  452. X
  453. X    }
  454. X    else {
  455. X
  456. X      /* write to a single user or tty
  457. X       */
  458. X
  459. X      switch (writeuser(&si)) {
  460. X      case RE_OK :
  461. X    ri.h.errno= RE_OK;
  462. X    ri.msg[0]= '\0';
  463. X    break;
  464. X      case RE_NOMSGS :
  465. X    ri.h.errno= RE_NOMSGS;
  466. X    sprintf(ri.msg,"%s@%s: User's messages are off, try mail instead",
  467. X        si.taddr,localhost);
  468. X    break;
  469. X      case RE_NOTTHERE :
  470. X    ri.h.errno= RE_NOTTHERE;
  471. X    sprintf(ri.msg,"%s@%s: User not found",si.taddr,localhost);
  472. X    break;
  473. X      case RE_NOUSER :
  474. X    ri.h.errno= RE_NOUSER;
  475. X    sprintf(ri.msg,"%s@%s: No such user",si.taddr,localhost);
  476. X    break;
  477. X      case RE_SYSERR :
  478. X    ri.h.errno= RE_SYSERR;
  479. X    strcpy(ri.msg,sys_errlist[errno]);
  480. X    break;
  481. X    default :
  482. X      error("internal error (this cannot happen!)");
  483. X    blderr(&ri,RE_INTERR,"Internal error in receiving daemon\n");
  484. X      }
  485. X    }
  486. X    sendreply(s,&ri,si.mode);
  487. X    if ((si.mode & SM_CLOSE) || (ri.h.errno != RE_OK))
  488. X      exit(0);
  489. X  }
  490. X}
  491. END_OF_FILE
  492.   if test 3606 -ne `wc -c <'domessage.c'`; then
  493.     echo shar: \"'domessage.c'\" unpacked with wrong size!
  494.   fi
  495.   # end of 'domessage.c'
  496. fi
  497. if test -f 'establish.c' -a "${1}" != "-c" ; then 
  498.   echo shar: Will not clobber existing file \"'establish.c'\"
  499. else
  500.   echo shar: Extracting \"'establish.c'\" \(938 characters\)
  501.   sed "s/^X//" >'establish.c' <<'END_OF_FILE'
  502. X/* establish.c:
  503. X *
  504. X * routine to establish a port for incoming connections
  505. X *
  506. X * this routine was originally written by Barry Shein (bzs@bu-it.bu.edu).
  507. X */
  508. X
  509. X#include "config.h"
  510. X#include "msend.h"
  511. X
  512. Xint establish(port)
  513. X#ifndef M_SYSV
  514. X     u_short port;
  515. X#else
  516. X     int port;
  517. X#endif
  518. X{ char   myname[MAXHOSTNAME+1];
  519. X  int    s;
  520. X  struct sockaddr_in sa;
  521. X  struct hostent *hp;
  522. X
  523. X  gethostname(myname,MAXHOSTNAME);            /* who are we? */
  524. X  bzero(&sa,sizeof(struct sockaddr_in));
  525. X  hp= gethostbyname(myname);                  /* get our address info */
  526. X  if (hp == NULL)                             /* we don't exist !? */
  527. X    return(-1);
  528. X  sa.sin_family= hp->h_addrtype;              /* set up info for new socket */
  529. X  sa.sin_port= htons(port);
  530. X  if ((s= socket(AF_INET,SOCK_STREAM,0)) < 0) /* make new socket */
  531. X    return(-1);
  532. X  if (bind(s,&sa,sizeof sa) < 0)
  533. X    return(-1);                               /* bind socket */
  534. X  return(s);
  535. X}
  536. END_OF_FILE
  537.   if test 938 -ne `wc -c <'establish.c'`; then
  538.     echo shar: \"'establish.c'\" unpacked with wrong size!
  539.   fi
  540.   # end of 'establish.c'
  541. fi
  542. if test -f 'fwdloop.c' -a "${1}" != "-c" ; then 
  543.   echo shar: Will not clobber existing file \"'fwdloop.c'\"
  544. else
  545.   echo shar: Extracting \"'fwdloop.c'\" \(720 characters\)
  546.   sed "s/^X//" >'fwdloop.c' <<'END_OF_FILE'
  547. X/* fwdloop.c:
  548. X *
  549. X * check for obvious forwarding loops
  550. X *
  551. X * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  552. X * the accompanying file "Copyright" for more information.
  553. X */
  554. X
  555. X#include "Copyright"
  556. X#include "config.h"
  557. X#include "msend.h"
  558. X
  559. X/* check for a local forwarding loop
  560. X */
  561. X
  562. Xint fwdloop(host)
  563. Xchar *host;
  564. X{ struct hostent *h;
  565. X  char hname[MAXHOSTNAME+1];
  566. X
  567. X  gethostname(hname,MAXHOSTNAME);
  568. X  h= gethostbyname(hname);
  569. X  if (strcmp(h->h_name,host)) {  /* obvious match? */
  570. X
  571. X    /* look through alias list to see if it's one of the possible names
  572. X     */
  573. X
  574. X    for (; (*h->h_aliases) && strcmp(*h->h_aliases,host); h->h_aliases++)
  575. X      ;
  576. X    return(*h->h_aliases != NULL);  
  577. X  }
  578. X  return(1);
  579. X}
  580. END_OF_FILE
  581.   if test 720 -ne `wc -c <'fwdloop.c'`; then
  582.     echo shar: \"'fwdloop.c'\" unpacked with wrong size!
  583.   fi
  584.   # end of 'fwdloop.c'
  585. fi
  586. if test -f 'gnugets.c' -a "${1}" != "-c" ; then 
  587.   echo shar: Will not clobber existing file \"'gnugets.c'\"
  588. else
  589.   echo shar: Extracting \"'gnugets.c'\" \(602 characters\)
  590.   sed "s/^X//" >'gnugets.c' <<'END_OF_FILE'
  591. X/* This file builds a simple case interface for the GNU 
  592. X * readline & history stuff.
  593. X * Spike (Spike@world.std.com) 10.11.90
  594. X */
  595. X
  596. X#include "Copyright"
  597. X#include "config.h"
  598. X#include "msend.h"
  599. X
  600. X#ifdef GNUREADLINE
  601. X#include <stdio.h>
  602. X
  603. Xchar *GNUGets (prompt)
  604. X     char *prompt;
  605. X{
  606. X  char *readline_buf, *readline();
  607. X
  608. X  /* Get a line from the user. */
  609. X  readline_buf = readline (prompt ? prompt : "");
  610. X
  611. X  /* If the line has any text in it, save it on the history. */
  612. X  if (readline_buf && *readline_buf)
  613. X    add_history (readline_buf);
  614. X
  615. X  return (readline_buf);
  616. X}
  617. X
  618. X#else
  619. Xstatic int boguscompilertrick;
  620. X#endif
  621. END_OF_FILE
  622.   if test 602 -ne `wc -c <'gnugets.c'`; then
  623.     echo shar: \"'gnugets.c'\" unpacked with wrong size!
  624.   fi
  625.   # end of 'gnugets.c'
  626. fi
  627. if test -f 'msend.h' -a "${1}" != "-c" ; then 
  628.   echo shar: Will not clobber existing file \"'msend.h'\"
  629. else
  630.   echo shar: Extracting \"'msend.h'\" \(4068 characters\)
  631.   sed "s/^X//" >'msend.h' <<'END_OF_FILE'
  632. X/* msend.h:
  633. X *
  634. X * header file for 'msend'
  635. X *
  636. X * (c) Copyright 1988 Jim Frost.  All Rights Reserved.  Please see
  637. X * the accompanying file "Copyright" for more information.
  638. X */
  639. X
  640. X#ifndef _MSEND_H_
  641. X#define _MSEND_H_
  642. X
  643. X#include "network.h"
  644. X#include <errno.h>
  645. X#include <pwd.h>
  646. X#include <signal.h>
  647. X#include <stdio.h>
  648. X#include <utmp.h>
  649. X#include <sys/types.h>
  650. X#include <sys/file.h>
  651. X#include <sys/ioctl.h>
  652. X#include <sys/socket.h>
  653. X#include <sys/stat.h>
  654. X#include <sys/wait.h>
  655. X#include <netinet/in.h>
  656. X#include <netdb.h>
  657. X
  658. X#define ROOTUID      0       /* system superuser uid */
  659. X#define DAEMONUID    1       /* system daemon uid */
  660. X#define MAXHOSTNAME  255     /* longest hostname we allow */
  661. X#define MAXFILENAME  1024    /* longest filename we allow */
  662. X#define MAXDEST      1024    /* longest destination path */
  663. X#define MAXUSERNAME  10      /* longest username we allow */
  664. X#define MAXTTY       10      /* longest tty (from utmp.h) */
  665. X#define MAXSIGNATURE 40      /* longest signature */
  666. X#define MAXMSG       1024    /* longest message text (includes signature) */
  667. X#define MAXLINE      128     /* longest text line in options file */
  668. X#define MAXTOKEN     30      /* longest allowable options file token */
  669. X#define MAXFORWARD   5       /* never forward more than this many hosts
  670. X                               (this prevents multiple host loops) */
  671. X#define BACKLOG      5       /* request backlog */
  672. X#define LIFETIME     (10*60) /* how long we live before we give up */
  673. X
  674. X/* message header for requests send to a daemon
  675. X */
  676. X
  677. Xstruct sheader {
  678. X  u_short taddrlen;  /* length of destination address field */
  679. X  u_short tttylen;   /* length of destination tty field */
  680. X  u_short msglen;    /* length of message field (includes signature) */
  681. X};
  682. X
  683. X#define SM_CLOSE     0x01 /* close connection after reply */
  684. X#define SM_TTY       0x02 /* send to tty */
  685. X#define SM_BROADCAST 0x04 /* broadcast */
  686. X#define SM_VERSION   0x08 /* version request */
  687. X
  688. X/* message header for replies sent back to the caller
  689. X */
  690. X
  691. Xstruct rheader {
  692. X  u_short  errno;
  693. X  u_short  msglen;
  694. X};
  695. X
  696. X#define RE_OK       0 /* message delivered ok */
  697. X#define RE_SYSERR   1 /* system error */
  698. X#define RE_NOUSER   2 /* user doesn't exist on this host */
  699. X#define RE_NOMSGS   3 /* user's terminal may not be written to */
  700. X#define RE_NOTTHERE 4 /* user is not logged on at the destination */
  701. X#define RE_NOROUTE  5 /* routing is denied at this host */
  702. X#define RE_NOBROAD  6 /* broadcasting is denied at this host */
  703. X#define RE_FWDLOOP  7 /* forwarding loop (too many forwards) */
  704. X#define RE_INTERR   8 /* something really really bad happened */
  705. X#define RE_NOTFATAL 9 /* non-fatal error print message don't exit */
  706. X
  707. X/* structures used for internal handling of messages
  708. X */
  709. X
  710. Xstruct simsg {
  711. X  u_short fwdcount;              /* number of times this has been forwarded */
  712. X  u_short mode;
  713. X  char    taddr[MAXDEST+1];
  714. X  char    ttty[MAXTTY+1];
  715. X  char    msg[MAXMSG+1];
  716. X  char    tohost[MAXHOSTNAME+1]; /* hostname to send message to */
  717. X};
  718. X
  719. Xstruct rimsg {
  720. X  struct rheader h;
  721. X  char   msg[MAXMSG+1];
  722. X};
  723. X
  724. X/* all global functions are defined here to make compilers and checkers
  725. X * happier.
  726. X */
  727. X
  728. X#undef A
  729. X#ifdef __STDC__
  730. X#define A(ARGS) ARGS
  731. X#else
  732. X#define A(ARGS) ()
  733. X#endif
  734. X
  735. Xint main A((int argc, char **argv));
  736. Xvoid domessage A((int s));
  737. Xint establish A((int port));
  738. Xint fwdloop A((char *host));
  739. Xvoid blderr A((struct rimsg *ri, int errno, char *msg));
  740. Xvoid die A((int i));
  741. Xvoid error A((char *s));
  742. Xint portnum A((void));
  743. Xchar *striphost A((char addr[], char *host));
  744. Xchar *gethome A((char *user));
  745. Xint getid A((char *user));
  746. X
  747. Xvoid sendmessage A((struct simsg *si, struct rimsg *ri, int mode));
  748. Xvoid sendreply A((int s, struct rimsg *ri, int mode));
  749. Xvoid recvmessage A((int s, struct simsg *si));
  750. Xstruct utmp *getutent A((void));
  751. Xvoid endutent A((void));
  752. Xchar *whoami A((void));
  753. Xvoid broadcast A((struct simsg *si));
  754. Xint writeuser A((struct simsg *si));
  755. X
  756. X#ifdef NEEDS_LOCK
  757. X#ifndef LOCK_EX /* sometimes fcntl has these even though there's no flock */
  758. X#define LOCK_EX 1
  759. X#define LOCK_UN 2
  760. X#endif
  761. Xint flock A((int fd, int how));
  762. X#endif
  763. X
  764. X#endif _MSEND_H_
  765. END_OF_FILE
  766.   if test 4068 -ne `wc -c <'msend.h'`; then
  767.     echo shar: \"'msend.h'\" unpacked with wrong size!
  768.   fi
  769.   # end of 'msend.h'
  770. fi
  771. if test -f 'msend.man' -a "${1}" != "-c" ; then 
  772.   echo shar: Will not clobber existing file \"'msend.man'\"
  773. else
  774.   echo shar: Extracting \"'msend.man'\" \(4198 characters\)
  775.   sed "s/^X//" >'msend.man' <<'END_OF_FILE'
  776. X.TH MSEND 1 "11 Dec member 1991"
  777. X.SH NAME
  778. Xmsend \- send an immediate message to another user
  779. X.SH SYNOPSIS
  780. X.B msend
  781. Xuser[@host] [message]
  782. X.br
  783. X.B msend .
  784. X[message]
  785. X.br
  786. X.B msend
  787. X\-clean
  788. X.br
  789. X.B msend
  790. X\-Tttyname [@host] [message]
  791. X.br
  792. X.B msend
  793. X\-B @host [message]
  794. X.br
  795. X.B msend
  796. X\-huh [# of messages]
  797. X.SH DESCRIPTION
  798. X\fIMsend\fR is used to send immediate messages to other users.  It
  799. Xoperates both locally and between hosts.  If configured to do so, it
  800. Xhas the ability to broadcast to all users on a machine and/or allow
  801. Xmanual routing of messages to other hosts.
  802. X.PP
  803. XA dot (.) in place of a username indicates an attempt to send to the
  804. Xsame user as the last invocation.  The username of the last send is
  805. Xstored in ~/.lastmsend.
  806. X.PP
  807. X
  808. XIf a message is specified on the command line, an attempt is made to
  809. Xsend the message to the specified user, tty, or host.  If no message
  810. Xis specified, \fImsend\fR goes into an interactive mode, sending each
  811. Xtyped line to the specified user.  Interactive mode can be exited via
  812. Xend-of-file or a dot (.) alone on a line.
  813. X.SH ROUTING
  814. XIn some environments, it may be necessary to route a message by hand
  815. Xin order to reach a specific host.  \fIMsend\fR allows you to specify
  816. Xa list of host names which will be read from right to left until an
  817. Xerror occurs or until the last host in the list.  Routing is allowed
  818. Xanywhere @host may be used.
  819. X.PP
  820. XSince some administrators may not want users routing messages to
  821. Xnon-local systems, routing may be disabled at compilation time.  An
  822. Xerror message is returned whenever a daemon with disabled routing is
  823. Xencountered.
  824. X.SH OPTIONS
  825. XThe following options are available with \fImsend\fR.
  826. X.TP 8
  827. X\fB-Tttyname [@host]\fR
  828. XSpecify a specific terminal (optionally on a different host) to send a
  829. Xmessage to.
  830. X.TP
  831. X\fB-B @host\fR
  832. XAttempt to broadcast to all users on the indicated system.
  833. XBroadcasting can be disabled at the client and/or the daemon at
  834. Xcompilation time, allowing the system administrator to control
  835. Xincoming or outgoing broadcast messages.  All broadcast messages are
  836. Xlogged.
  837. X.TP
  838. X\fB-clean\fR
  839. XErase the file of old messages.
  840. X.TP
  841. X\fB-edit\fR
  842. XToggle command line editing if using the GNU Readline interface.
  843. X.TP
  844. X\fB-huh [# of messages]\fR
  845. XReprint the last message (or messages) that were sent to you on this
  846. Xhost.
  847. X.SH OPTIONS FILE
  848. XTo allow a user to tailor his message environment, the send programs
  849. Xlook for .msendrc in the user's home directory.  The "signature" option
  850. Xis the only option that affects outgoing messages; all others affect
  851. Xincoming messages.  The options are:
  852. X.TP
  853. X\fBsignature "format string"\fR
  854. XThis is used to allow customization of messages that you send to other
  855. Xusers.  The string within quotes will be appended to your name and
  856. Xhost when the message is sent.  If %d or %t is included in the string,
  857. Xthe date or your tty (respectively) will be inserted in its place.
  858. X.TP
  859. X\fBallttys\fR
  860. XAttempt to write to all ttys owned by the intended recipient on the
  861. Xlocal host.
  862. X.TP
  863. X\fBforward-to-user user[@host]\fR
  864. XInstead of writing to this user, forward the message to another user.
  865. XThis is especially useful when you have multiple accounts.
  866. X.TP
  867. X\fBwrite-and-forward user[@host]\fR
  868. XThis is similar to forward-to-user, but will also attempt to write to
  869. Xthe user locally.
  870. X.TP
  871. X\fBwrite-on-tty ttyname\fR
  872. XAttempt to write to a particular local tty.  This is
  873. Xuseful with workstations to force writes to a particular window.
  874. X.TP
  875. X\fBforward-to-tty ttyname @host\fP
  876. XAttempt to write to a given tty on the indicated host.
  877. X.TP
  878. X\fBhistory number\fP
  879. XNumber of lines of history to keep if using the GNU Readline
  880. Xinterface.  The default is unlimited.
  881. X.TP
  882. X\fBediting_mode "emacs"|"vi"\fP
  883. XUse emacs- or vi-style command line editing if using the GNU Readline
  884. Xinterface.  The default is emacs-style.
  885. X.TP
  886. X\fBedit "on"|"off"\fP
  887. XEnable or disable command line editing if using the GNU Readline
  888. Xinterface.  The default is site dependant, but tends to be off as GNU
  889. XReadline interface has problems on some terminals.
  890. X.SH AUTHORS
  891. X.nf
  892. XJim Frost
  893. X\fBjimf@centerline.com\fP
  894. X.LP
  895. XJoe Ilacqua
  896. X\fBspike@world.std.com\fP
  897. X.fi
  898. X.SH FILES
  899. X.PP
  900. X~/.lastmsend
  901. X.br
  902. X~/.msendrc
  903. X.br
  904. X/usr/spool/msend/*
  905. X.br
  906. X/usr/adm/msend.log
  907. X.SH BUGS
  908. XIf you find any, let us know.
  909. X
  910. END_OF_FILE
  911.   if test 4198 -ne `wc -c <'msend.man'`; then
  912.     echo shar: \"'msend.man'\" unpacked with wrong size!
  913.   fi
  914.   # end of 'msend.man'
  915. fi
  916. if test -f 'msendd.c' -a "${1}" != "-c" ; then 
  917.   echo shar: Will not clobber existing file \"'msendd.c'\"
  918. else
  919.   echo shar: Extracting \"'msendd.c'\" \(3790 characters\)
  920.   sed "s/^X//" >'msendd.c' <<'END_OF_FILE'
  921. X/* msendd.c:
  922. X *
  923. X * daemon required to allow msend to operate.  works with inetd also.
  924. X *
  925. X * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  926. X * the accompanying file "Copyright" for more information.
  927. X *
  928. X * special thanks to Barry Shein (bzs@bu-it.bu.edu) for the skeleton
  929. X * that this was built from.
  930. X */
  931. X
  932. X#include "Copyright"
  933. X#include "config.h"
  934. X#include "msend.h"
  935. X
  936. X#ifdef ROUTE
  937. Xshort doroute = 1;
  938. X#endif
  939. X
  940. X#ifdef DBROADCAST
  941. Xshort dobroadcast = 1;
  942. X#endif
  943. X
  944. X#ifdef SECURE_PORT
  945. Xshort notsecure = 1;
  946. X#endif
  947. X
  948. Xstatic void fireman()    /* catches falling babies */
  949. X{ WAIT_STATUS wstatus;
  950. X
  951. X  while(wait3(&wstatus,WNOHANG,NULL) > 0);
  952. X}
  953. X
  954. Xstatic void sigint()
  955. X{ error("SIGINT interrupt received");
  956. X  die(0);
  957. X}
  958. X
  959. Xstatic void sigterm()
  960. X{ error("SIGTERM interrupt received");
  961. X  die(0);
  962. X}
  963. X
  964. X
  965. Xmain(argc,argv)
  966. X     int argc;
  967. X     char *argv[];
  968. X{ 
  969. X  char c;
  970. X  int s,t;
  971. X  int i;
  972. X  struct sockaddr_in isa;
  973. X  extern int errno;
  974. X
  975. X
  976. X  while ((c = getopt(argc, argv, "rb")) != (char) -1) {
  977. X    switch(c) {
  978. X    case 'r':
  979. X#ifdef ROUTE
  980. X      doroute = 0;
  981. X#endif
  982. X      break;
  983. X    case 'b':
  984. X#ifdef DBROADCAST
  985. X      dobroadcast = 0;
  986. X#endif
  987. X      break;
  988. X    }
  989. X  }
  990. X
  991. X#ifndef ALONE
  992. X  /* inetd(8), don't leave home without it */
  993. X#ifdef SECURE_PORT
  994. X  i = sizeof(isa);
  995. X  s = 0; /* stdin */
  996. X  if (getpeername(s,(struct sockaddr *)&isa,&i) >= 0){
  997. X    if ((ntohs(isa.sin_port) < IPPORT_RESERVED)
  998. X    && (ntohs(isa.sin_port) > IPPORT_RESERVED/2))
  999. X      notsecure = 0;
  1000. X  }
  1001. X#endif
  1002. X  domessage(0);
  1003. X  exit(0);
  1004. X
  1005. X#else
  1006. X  /* disassociate ourselves from any terminal
  1007. X   */
  1008. X
  1009. X  for (i= 0; i < getdtablesize(); i++)
  1010. X    close(i);
  1011. X  if ((i= open("/dev/tty", O_RDWR)) >= 0) {
  1012. X    if (ioctl(i, TIOCNOTTY, NULL) < 0)
  1013. X      error("Can't disassociate from tty\n");
  1014. X    close(i);
  1015. X  }
  1016. X
  1017. X  /* normal daemon.  set up for listening and then go into an infinite
  1018. X   * loop for connections
  1019. X   */
  1020. X
  1021. X  error("msendd started");           /* remember when it all started */
  1022. X  if ((s= establish(portnum())) < 0) { /* bind to a socket */
  1023. X    if (errno == EADDRINUSE) {
  1024. X      printf("msendd: cannot allocate port (daemon already active?)\n");
  1025. X    }
  1026. X    else
  1027. X      perror("msendd: establish");
  1028. X    die(1);
  1029. X  }
  1030. X
  1031. X  /* an ioctl should go here after openning /dev/tty but i can't remember
  1032. X   * which ioctl
  1033. X   */
  1034. X
  1035. X  switch (fork()) {
  1036. X  case -1: /* oh well */
  1037. X    error("can't fork, sorry\n");
  1038. X  case 0:
  1039. X    break;
  1040. X  default:
  1041. X    exit(0);
  1042. X  }
  1043. X
  1044. X  /* after establishing ourselves, become DAEMONUID
  1045. X   */
  1046. X
  1047. X  if (getuid() == ROOTUID)
  1048. X    seteuid(DAEMONUID);
  1049. X
  1050. X  i = sizeof(isa);                   /* find it's "name" */
  1051. X  getsockname(s,&isa,&i);
  1052. X  signal(SIGHUP,SIG_IGN);
  1053. X  signal(SIGSTOP,SIG_IGN);           /* bad things happened w/o this */
  1054. X  signal(SIGTSTP,SIG_IGN);           /* seems to get this sometimes */
  1055. X  signal(SIGINT,sigint);
  1056. X  signal(SIGTERM,sigterm);
  1057. X  signal(SIGCHLD,fireman);           /* set up to catch dead children */
  1058. X  listen(s,BACKLOG);                 /* set maximum backlog */
  1059. X
  1060. X  for(;;) {
  1061. X    i = sizeof isa ;
  1062. X    if((t = accept(s,&isa,&i)) < 0) {
  1063. X      if(errno != EINTR)             /* we'll get an EINTR when child dies */
  1064. X    error("accept error");
  1065. X      continue;                         /* try again */
  1066. X    }
  1067. X
  1068. X    if (fork() == 0) {
  1069. X      close(s);                      /* i have no need for you */
  1070. X      setpgrp(0, getpid());          /* parent doesn't want signals! */
  1071. X#ifdef SECURE_PORT
  1072. X      if (getpeername(t,(struct sockaddr *)&isa,&i) >= 0){
  1073. X    if ((ntohs(isa.sin_port) < IPPORT_RESERVED)
  1074. X        && (ntohs(isa.sin_port) > IPPORT_RESERVED/2))
  1075. X      notsecure = 0;
  1076. X      }
  1077. X#endif
  1078. X      domessage(t);                  /* process the message(s) */
  1079. X      exit(0);                       /* domessage does this too */
  1080. X    }
  1081. X
  1082. X    /* fork errors disconnect immediately, tough luck on the user
  1083. X     */
  1084. X
  1085. X    else
  1086. X      close(t);
  1087. X  }
  1088. X#endif
  1089. X}
  1090. X
  1091. X
  1092. END_OF_FILE
  1093.   if test 3790 -ne `wc -c <'msendd.c'`; then
  1094.     echo shar: \"'msendd.c'\" unpacked with wrong size!
  1095.   fi
  1096.   # end of 'msendd.c'
  1097. fi
  1098. if test -f 'network.h' -a "${1}" != "-c" ; then 
  1099.   echo shar: Will not clobber existing file \"'network.h'\"
  1100. else
  1101.   echo shar: Extracting \"'network.h'\" \(483 characters\)
  1102.   sed "s/^X//" >'network.h' <<'END_OF_FILE'
  1103. X/* network.h:
  1104. X *
  1105. X * definitions for the raw network interface
  1106. X *
  1107. X * (c) Copyright 1988 Jim Frost.  All Rights Reserved.  Please see
  1108. X * the accompanying file "Copyright" for more information.
  1109. X */
  1110. X
  1111. X#ifndef __NETWORK__
  1112. X#undef A
  1113. X#ifdef __STDC__
  1114. X#define A(ARGS) ARGS
  1115. X#else
  1116. X#define A(ARGS) ()
  1117. X#endif
  1118. X
  1119. Xint hopen A((char *hostname));
  1120. Xvoid hclose A((int s));
  1121. Xvoid hcleanup A((void));
  1122. Xint hread A((int s, char *buf, int n));
  1123. Xint hwrite A((int s, char *buf, int n));
  1124. X#define __NETWORK__
  1125. X#endif
  1126. END_OF_FILE
  1127.   if test 483 -ne `wc -c <'network.h'`; then
  1128.     echo shar: \"'network.h'\" unpacked with wrong size!
  1129.   fi
  1130.   # end of 'network.h'
  1131. fi
  1132. if test -f 'patchlevel' -a "${1}" != "-c" ; then 
  1133.   echo shar: Will not clobber existing file \"'patchlevel'\"
  1134. else
  1135.   echo shar: Extracting \"'patchlevel'\" \(301 characters\)
  1136.   sed "s/^X//" >'patchlevel' <<'END_OF_FILE'
  1137. X/* patchlevel:
  1138. X *
  1139. X * version information for 'msend'
  1140. X *
  1141. X * (c) Copyright 1991 Jim Frost.  All Rights Reserved.  Please see
  1142. X * the accompanying file "Copyright" for more information.
  1143. X */
  1144. X
  1145. X#define VERSION "1"
  1146. X#define PATCHLEVEL "2"
  1147. X#define MADD "jimf@centerline.com"
  1148. X#define SPIKE "spike@world.std.com"
  1149. END_OF_FILE
  1150.   if test 301 -ne `wc -c <'patchlevel'`; then
  1151.     echo shar: \"'patchlevel'\" unpacked with wrong size!
  1152.   fi
  1153.   # end of 'patchlevel'
  1154. fi
  1155. if test -f 'utmp.c' -a "${1}" != "-c" ; then 
  1156.   echo shar: Will not clobber existing file \"'utmp.c'\"
  1157. else
  1158.   echo shar: Extracting \"'utmp.c'\" \(1347 characters\)
  1159.   sed "s/^X//" >'utmp.c' <<'END_OF_FILE'
  1160. X/* utmp.c:
  1161. X *
  1162. X * these routines are for manipulating the utmp file.  these were written
  1163. X * by Phil Budne (budd@bu-it.bu.edu) originally.
  1164. X */
  1165. X
  1166. X#include "config.h"
  1167. X#include "msend.h"
  1168. X
  1169. Xstatic FILE *uf;            /* utmp file */
  1170. X#ifndef _PATH_UTMP
  1171. X#define _PATH_UTMP      "/etc/utmp"
  1172. X#endif
  1173. X
  1174. Xstatic char *utmpfile = _PATH_UTMP;    /* utmp file name */
  1175. X
  1176. X/* open the utmp file if necessary and read one entry at a time
  1177. X */
  1178. X
  1179. Xstruct utmp *getutent()
  1180. X{ static struct utmp ubuf;
  1181. X  struct stat   stb;
  1182. X
  1183. X  /* verify that utmp file is a reasonable size
  1184. X   */
  1185. X
  1186. X  if (uf == NULL) {
  1187. X    if (stat(utmpfile,&stb) == 0 ) {
  1188. X      if ((stb.st_size % sizeof(struct utmp)) != 0) {
  1189. X        return(NULL);
  1190. X      }
  1191. X    }
  1192. X    else
  1193. X      return(NULL);
  1194. X
  1195. X    /* open utmp
  1196. X     */
  1197. X
  1198. X    if ((uf= fopen(utmpfile,"r")) == NULL) /* was '< 0' -20 Mar 89-composer */
  1199. X      return(NULL);
  1200. X  }
  1201. X
  1202. X  /* read next utmp entry and return it if we can
  1203. X   */
  1204. X
  1205. X  if (fread(&ubuf,sizeof(ubuf),1,uf) == 0 ) {
  1206. X    fseek(uf,0L,0);
  1207. X    return(NULL);
  1208. X  }
  1209. X
  1210. X/* fix for problem with ut_name containing both ut_name and ut_host */
  1211. X/*   when the size of ut_name = 8 .. - 20 Mar 89 - composer         */
  1212. X/*   one slight side effect - kills 1st char of ut_host             */
  1213. X  ubuf.ut_name[8] = '\0';
  1214. X  return(&ubuf);
  1215. X}
  1216. X
  1217. X/* close utmp file
  1218. X */
  1219. X
  1220. Xvoid endutent()
  1221. X{
  1222. X  if(uf != NULL) {
  1223. X    fclose(uf);
  1224. X    uf= NULL;
  1225. X  }
  1226. X}
  1227. X
  1228. X
  1229. X
  1230. END_OF_FILE
  1231.   if test 1347 -ne `wc -c <'utmp.c'`; then
  1232.     echo shar: \"'utmp.c'\" unpacked with wrong size!
  1233.   fi
  1234.   # end of 'utmp.c'
  1235. fi
  1236. if test -f 'whoami.c' -a "${1}" != "-c" ; then 
  1237.   echo shar: Will not clobber existing file \"'whoami.c'\"
  1238. else
  1239.   echo shar: Extracting \"'whoami.c'\" \(723 characters\)
  1240.   sed "s/^X//" >'whoami.c' <<'END_OF_FILE'
  1241. X/* whoami.c:
  1242. X *
  1243. X * this attempts to figure out who ran the program
  1244. X *
  1245. X * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  1246. X * the accompanying file "Copyright" for more information.
  1247. X */
  1248. X
  1249. X#include "Copyright"
  1250. X#include "config.h"
  1251. X#include "msend.h"
  1252. X#ifndef M_SYSV
  1253. X#include <string.h>
  1254. Xextern char *getlogin();
  1255. X#endif
  1256. X
  1257. Xchar *whoami()
  1258. X{ struct passwd *pwd;
  1259. X  static char   name[MAXUSERNAME+1];
  1260. X  static int    unknown= 1;
  1261. X
  1262. X  if (unknown) {
  1263. X    if ((pwd= getpwuid(getuid())) == NULL) {
  1264. X      if (strcpy(name,getlogin()) == NULL) {
  1265. X        printf("Who are you?  (No password file entry?)\n");
  1266. X        exit(1);
  1267. X      }
  1268. X    }
  1269. X    else
  1270. X      strcpy(name,pwd->pw_name);
  1271. X    unknown= 0;
  1272. X  }
  1273. X  return(name);
  1274. X}
  1275. END_OF_FILE
  1276.   if test 723 -ne `wc -c <'whoami.c'`; then
  1277.     echo shar: \"'whoami.c'\" unpacked with wrong size!
  1278.   fi
  1279.   # end of 'whoami.c'
  1280. fi
  1281. echo shar: End of archive 2 \(of 2\).
  1282. cp /dev/null ark2isdone
  1283. MISSING=""
  1284. for I in 1 2 ; do
  1285.     if test ! -f ark${I}isdone ; then
  1286.     MISSING="${MISSING} ${I}"
  1287.     fi
  1288. done
  1289. if test "${MISSING}" = "" ; then
  1290.     echo You have unpacked both archives.
  1291.     rm -f ark[1-9]isdone
  1292. else
  1293.     echo You still must unpack the following archives:
  1294.     echo "        " ${MISSING}
  1295. fi
  1296. exit 0
  1297. exit 0 # Just in case...
  1298.