home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / vmsnet / sources / 358 < prev    next >
Encoding:
Internet Message Format  |  1992-09-04  |  39.5 KB

  1. Path: sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sources
  2. Newsgroups: vmsnet.sources
  3. From: gerland@ubvmsb.cc.buffalo.edu (Jim Gerland)
  4. Subject: ISEND for VMS, part 01/01
  5. Date: Fri, 04 Sep 1992 06:12:44 GMT
  6. Message-ID: <8045724@MVB.SAIC.COM>
  7. Keywords: ISEND TALK MSP
  8. Reply-To: gerland@ubvmsb.cc.buffalo.edu
  9. Organization: University at Buffalo
  10. Lines: 1185
  11. Approved: Mark.Berryman@Mvb.Saic.Com
  12.  
  13. Submitted-by: gerland@ubvmsb.cc.buffalo.edu (Jim Gerland)
  14. Posting-number: Volume 3, Issue 163
  15. Archive-name: isend/part01
  16.  
  17.          [ This submission is an implementation of the messaging
  18.            protocol described in RFC 1312 (an earlier version of
  19.            this protocol is described in RFC 1159).  This protocol
  20.            provides a means of sending messages to a remote user's
  21.            terminal using UDP datagrams. ]
  22.  
  23. $! ------------------ CUT HERE -----------------------
  24. $ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
  25. $!
  26. $! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
  27. $!   On 12-AUG-1992 08:34:25.46   By user GERLAND (Jim Gerland - University at Buffalo)
  28. $!
  29. $! This VMS_SHARE Written by:
  30. $!    Andy Harper, Kings College London UK
  31. $!
  32. $! Acknowledgements to:
  33. $!    James Gray       - Original VMS_SHARE
  34. $!    Michael Bednarek - Original Concept and implementation
  35. $!
  36. $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
  37. $! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
  38. $!
  39. $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
  40. $!       1. AAAREADME.TXT;12
  41. $!       2. COMPILE.;2
  42. $!       3. COMPILE.COM;6
  43. $!       4. ISEND.C;41
  44. $!       5. ISEND.HLP;1
  45. $!       6. ISEND.OPT;2
  46. $!       7. ISEND.RNH;5
  47. $!       8. ISENDD.C;48
  48. $!       9. MAKEFILE.;5
  49. $!      10. MULTINET.OPT;2
  50. $!      11. START-ISEND-SERVER.COM;3
  51. $!      12. UNIX_BRDCST.C;3
  52. $!      13. VMS_BROADCAST.C;7
  53. $!      14. WIN.OPT;3
  54. $!
  55. $set="set"
  56. $set symbol/scope=(nolocal,noglobal)
  57. $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
  58. $e="write sys$error  ""%UNPACK"", "
  59. $w="write sys$output ""%UNPACK"", "
  60. $ if f$trnlnm("SHARE_LOG") then $ w = "!"
  61. $ ve=f$getsyi("version")
  62. $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
  63. $ e "-E-OLDVER, Must run at least VMS 4.4"
  64. $ v=f$verify(v)
  65. $ exit 44
  66. $UNPACK: SUBROUTINE ! P1=filename, P2=checksum
  67. $ if f$search(P1) .eqs. "" then $ goto file_absent
  68. $ e "-W-EXISTS, File ''P1' exists. Skipped."
  69. $ delete 'f'*
  70. $ exit
  71. $file_absent:
  72. $ if f$parse(P1) .nes. "" then $ goto dirok
  73. $ dn=f$parse(P1,,,"DIRECTORY")
  74. $ w "-I-CREDIR, Creating directory ''dn'."
  75. $ create/dir 'dn'
  76. $ if $status then $ goto dirok
  77. $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
  78. $ delete 'f'*
  79. $ exit
  80. $dirok:
  81. $ w "-I-PROCESS, Processing file ''P1'."
  82. $ if .not. f$verify() then $ define/user sys$output nl:
  83. $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
  84. PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
  85. SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
  86. CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
  87. LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
  88. BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
  89. IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
  90. MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
  91. ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
  92. 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
  93. POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
  94. ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
  95. COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
  96. "output_file"));ENDPROCEDURE;Unpacker;QUIT;
  97. $ delete/nolog 'f'*
  98. $ CHECKSUM 'P1'
  99. $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
  100. $ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
  101. $ ENDSUBROUTINE
  102. $START:
  103. $ create 'f'
  104. XCOPYRIGHT NOTICE:
  105. X  This program was written at the Hebrew University and is given for a publi
  106. Vc
  107. X use as long as it is used for non-profit interests. The Hebrew university
  108. X is not responsible for any damage that might be caused due to use or mis-us
  109. Ve
  110. X of this software. It is given as-is with no waranty.
  111. X
  112. X
  113. XISEND is the implementation for Unix and VMS systems of RFC-1159 and RFC-131
  114. V2.
  115. XIt will compile on most Unix systems and on VMS systems that use MultiNet.
  116. X  The headers of ISEND.C and ISENDD.C describe how to compile, link and run
  117. Xthem.
  118. X
  119. X Note for AIX: The compilation variable "unix" is not defined on these syste
  120. Vms
  121. Xas it is on other Unix systems. You have to enter
  122. X#define unix
  123. Xat each source file, and then you'll have hard work to make it compiling...
  124. X
  125. X  Note for Ultrix: Remove the line that include <fcntl.h>
  126. X
  127. X  Note for Wollogong:  Modified 11-Aug-1992,`20
  128. X                       by Jim Gerland,`20
  129. X                          University at Buffalo,`20
  130. X                          - to run under WINTCP 5.2
  131. X                          - created makefile.
  132. X                          - modified compile.com to use isend.opt file
  133. X                          - created start-isend-server.com
  134. X
  135. X  Note for UCX: I haven't checked it on these systems. However, you should`2
  136. V0
  137. Xmodify the include files and link with the appropriate library.
  138. X
  139. X  Note for MultiNet: If you are using Multinet 2.2 (and not 3.0) then
  140. Xrename ISENDD.C_V22 to ISENDD.C before compiling.
  141. X
  142. XRUNNING the background process: The program ISEND should be run at the
  143. Xbackground. On VMS it should be run like:
  144. X
  145. X$ RUN/DETACH/INPUT=NL:/OUTPUT=NL:/ERROR=NL:/PROCESS_NAME="ISEND_task" -
  146. X  /PRIV=(NOALL,TMPMBX,NETMBX,OPER) -
  147. X  UTIL$:ISENDD
  148. X
  149. XOPER is needed in order to broadcast messages.
  150. X
  151. XOn Unix it should be run like:
  152. X
  153. X% isendd
  154. X
  155. Xand it will fork by itself.
  156. X
  157. X  Bugs should be reported to YEHAVI@VMS.HUJI.AC.IL
  158. X
  159. X
  160. XRFC-1312 compatibility: The program was originaly written according to RFC-1
  161. V159.
  162. XThe server was then upgraded to support RFC-1312 as well (ignoring the new
  163. Xfields). The client is left with the old version in order to communicate
  164. Xwith older implementations of ISENDD.
  165. X
  166. X
  167. XFILES INCLUDED:
  168. X
  169. XAAAREADME.TXT - This file.
  170. XISEND.1       - Man page for Unix systems.
  171. XISEND.RNH     - Help file for VMS. RUNOFF it.
  172. XISEND.C       - The client program.
  173. XISENDD.C      - The background daemon.
  174. XUNIX_BRDCST.C - Linked with ISENDD on Unix systems.
  175. XVMS_BROADCAST.C - Linked with ISENDD on VMS systems.
  176. XCOMPILE.COM   - DCL procedure to compile on VMS
  177. XCOMPILE       - Unix procedure for compilation.
  178. $ CALL UNPACK AAAREADME.TXT;12 520155160
  179. $ create 'f'
  180. Xcc -o isend isend.c
  181. Xcc -o isendd isendd.c unix_brdcst.c
  182. $ CALL UNPACK COMPILE.;2 507200431
  183. $ create 'f'
  184. X$ CC/NOLIST ISEND /DEFINE=WINTCP
  185. X$ CC/NOLIST ISENDD /DEFINE=WINTCP
  186. X$ CC/NOLIST VMS_BROADCAST
  187. X$ LINK ISEND,ISEND.OPT/OPTION
  188. X$ LINK ISENDD,VMS_BROADCAST,ISEND.OPT/OPTION
  189. X$ EXIT
  190. $ CALL UNPACK COMPILE.COM;6 556285164
  191. $ create 'f'
  192. X/* ISEND.C`09V1.0
  193. X `7C  This program was written at the Hebrew University and is given for a p
  194. Vublic
  195. X `7C use as long as it is used for non-profit interests. The Hebrew universi
  196. Vty
  197. X `7C is not responsible for any damage that might be caused due to use or mi
  198. Vs-use
  199. X `7C of this software. It is given as-is with no waranty.
  200. X `7C
  201. X `7C  This is the client program for the InterNet SEND protocol as described
  202. V in
  203. X `7C RFC-1159. It will compile on Unix and VMS systems (using MultiNet). On
  204. X `7C IBM-AIX systems it must be compiled with the compilation variable "unix
  205. V"
  206. X `7C defined (it is defined by the compiler on other Unix systems).
  207. X `7C
  208. X `7C USAGE:
  209. X `7C   ISEND InternetAddress  Message
  210. X `7C will use UDP interface, and:
  211. X `7C   ISEND InternetAddress
  212. X `7C will request the text from the user line by line and will use TCP conne
  213. Vction.
  214. X `7C
  215. X `7C Modified: 11-Aug-1992
  216. X `7C           Jim Gerland (JRG)
  217. X `7C           University at Buffalo
  218. X `7C           Added #ifdefs for Multinet & Wollongong
  219. X `7C
  220. X `7C On VMS it should be linked with the command:
  221. X `7C $ LINK /EXE=ISEND.EXE ISEND.OBJ,ISEND.OPT/OPTION
  222. X `7C and define it as a foreign DCL command.
  223. X */
  224. X#include <stdio.h>
  225. X#ifdef unix
  226. X#include <sys/types.h>
  227. X#include <sys/socket.h>
  228. X#include <netdb.h>
  229. X#endif /* unix */
  230. X
  231. X#ifdef MULTINET
  232. X#include "multinet_root:`5Bmultinet.include.sys`5Dtypes.h"
  233. X#include "multinet_root:`5Bmultinet.include.sys`5Dsocket.h"
  234. X#include "multinet_root:`5Bmultinet.include`5Dnetdb.h"
  235. X/* The following are for Multinet's library: */
  236. X#define`09close`09socket_close
  237. X#define`09write`09socket_write
  238. X#define`09read`09socket_read
  239. X#define`09perror`09socket_perror
  240. X#endif /* MULTINET */
  241. X
  242. X/*  JRG 11-Aug-1992 */
  243. X#ifdef WINTCP
  244. X#include "twg$tcp:`5Bnetdist.include.sys`5Dtypes.h"
  245. X#include "twg$tcp:`5Bnetdist.include.sys`5Dsocket.h"
  246. X#include "twg$tcp:`5Bnetdist.include`5Dnetdb.h"
  247. X#endif /* WINTCP */
  248. X
  249. X#define`09LINESIZE`091024`09`09/* Buffer size */
  250. X#define ISEND_PORT`0918`09`09/* UDP and TCP port 18 */
  251. X
  252. X#define`09UDP`090
  253. X#define`09TCP`091
  254. X
  255. Xchar`09LocalhostName`5B1024`5D;`09`09/* Store here the Internet name of us *
  256. V/
  257. X
  258. X/* This structure is the sockaddr structure usually used */
  259. Xstruct sockaddr_in `7B
  260. X`09short`09`09sin_family;`09/* family */
  261. X`09unsigned short`09sin_port;`09/* port number */
  262. X`09unsigned long`09sin_addr;`09/* Internet address */
  263. X`09char`09`09sin_zero`5B8`5D;`09/* unused, must be 0 */
  264. X`7D;
  265. X
  266. X
  267. X/*
  268. X `7C Find the local hostname, parse the parameters and dispatch.
  269. X */
  270. Xmain(cc, vv)
  271. Xchar`09**vv;
  272. Xint`09cc;
  273. X`7B
  274. X`09struct`09hostent`09*HostEntry;
  275. X`09char`09text`5BLINESIZE`5D,`09`09/* Construct here the message text */
  276. X`09`09address`5BLINESIZE`5D,`09/* To whome to send */
  277. X`09`09*p, *strchr();
  278. X`09unsigned int`09InternetAddress,`09/* IP address of host */
  279. X`09`09`09i, mode;`09`09/* Reliable to UDP */
  280. X
  281. X/* Get our local hostname */
  282. X`09if(gethostname(LocalhostName, sizeof(LocalhostName)) != 0) `7B
  283. X`09`09perror("Gethostname"); exit(1);
  284. X`09`7D
  285. X
  286. X/* See whether we have an address to send to */
  287. X`09if(cc < 2) `7B`09/* no... */
  288. X`09`09printf("Usage: ISEND  address  text\n"); exit(1);
  289. X`09`7D
  290. X
  291. X/* Get the hostname from the address */
  292. X`09strncpy(address, vv`5B1`5D, LINESIZE);
  293. X`09if((p = strchr(address, '@')) == NULL) `7B
  294. X`09`09p = &address`5Bstrlen(address)`5D;`09/* End of address - here will be
  295. V the @ */
  296. X`09`09strcat(address, "@localhost");`09/* Make it a local user if no hostnam
  297. Ve */
  298. X`09`7D
  299. X`09*p++ = '\0';`09/* Get to hostname and delimit username */
  300. X
  301. X/* Get the IP address of the host */
  302. X`09if((HostEntry = gethostbyname(p)) == NULL) `7B
  303. X`09`09perror("GetHostByName");
  304. X`09`09exit(1);
  305. X`09`7D
  306. X
  307. X`09if(HostEntry->h_length != 4) `7B`09/* Illegal */
  308. X`09`09printf("Illegal address length=%d\n", HostEntry->h_length);
  309. X`09`09exit(1);
  310. X`09`7D
  311. X
  312. X/* Assemble the address into a longword */
  313. X`09InternetAddress =`20
  314. X`09`09(((HostEntry->h_addr)`5B0`5D & 0xff) << 24) +
  315. X`09`09(((HostEntry->h_addr)`5B1`5D & 0xff) << 16) +
  316. X`09`09(((HostEntry->h_addr)`5B2`5D & 0xff) << 8) +
  317. X`09`09(((HostEntry->h_addr)`5B3`5D & 0xff));
  318. X
  319. X/* Get the parameters */
  320. X`09if(cc > 2) `7B`09/* The text is there */
  321. X`09`09mode = UDP;`09`09/* Use unrliable mode in this case */
  322. X`09`09/* Construct the text from the parameters */
  323. X`09`09*text = '\0';
  324. X`09`09for(i = 2; i < cc; i++) `7B
  325. X`09`09`09strcat(text, vv`5Bi`5D); strcat(text, " ");
  326. X`09`09`7D
  327. X`09`09text`5Bstrlen(text) - 1`5D = '\0';`09/* Remove the last blank */
  328. X`09`09send_message(InternetAddress, address, mode, text);
  329. X`09`09exit(1);
  330. X`09`7D
  331. X`09else
  332. X`09`09mode = TCP;`09/* No text - have to read it and we'll also use reliable
  333. V mode */
  334. X
  335. X
  336. X/* We have to read it interactively. Loop untill blank line */
  337. X`09printf("Hit your message. End with empty line\n");
  338. X`09for(;;) `7B
  339. X`09`09printf("%s: ", address);
  340. X`09`09if(fgets(text, sizeof text, stdin) == NULL)
  341. X`09`09`09break;`09/* Null line */
  342. X`09`09if((p = (char*)strchr(text, '\n')) != NULL) *p = '\0';
  343. X`09`09if(*text == '\0') break;`09/* Another sign of empty line */
  344. X`09`09send_message(InternetAddress, address, mode, text);
  345. X`09`7D
  346. X`09exit(0);
  347. X`7D
  348. X
  349. X
  350. X/*
  351. X `7C Send the given text to the given IP address. USe UDP or TCP as requeste
  352. Vd in
  353. X `7C mode argument.
  354. X */
  355. Xsend_message(InternetAddress, ToUsername, mode, text)
  356. Xunsigned int`09mode,`09`09/* TCP or UDP */
  357. X`09`09InternetAddress;
  358. Xchar`09*ToUsername, *text;
  359. X`7B
  360. X`09unsigned char`09*p, line`5BLINESIZE`5D,
  361. X`09`09`09from`5BLINESIZE`5D;`09/* Construct the sender's address here */
  362. X`09struct`09sockaddr_in`09SocketName;
  363. X`09int`09Socket, i, size;
  364. X
  365. X/* Remove all controls */
  366. X`09for(p = (unsigned char *)text; *p != '\0'; *p++)
  367. X`09`09if((*p < ' ') `7C`7C (*p > '\176')) *p = ' ';
  368. X
  369. X/* Create the sender's address. We preceed the message with it for clarity *
  370. V/
  371. X`09cuserid(from); strcat(from, "@"); strcat(from, LocalhostName);
  372. X
  373. X/* Create the message buffer:
  374. X   A - Protocol version 1.
  375. X   Username (Null terminated)
  376. X   Terminal name (Null terminated) - we use an empty terminal name
  377. X   Text
  378. X*/
  379. X`09sprintf(line, "A%s", ToUsername);
  380. X`09size = strlen(line);`09/* First part - A + username */
  381. X`09line`5Bsize++`5D = '\0';`09/* Null - end of username (just for programmin
  382. Vg beauti... */
  383. X`09line`5Bsize++`5D = '\0';`09/* Null terminal name (Sprintf can't print two
  384. V nulls */
  385. X`09sprintf(&line`5Bsize`5D, "%s: %s", from, text);
  386. X`09size += (strlen(&line`5Bsize`5D) + 1);`09/* +1 for the terminating null *
  387. V/
  388. X
  389. X/* Create a local socket */
  390. X`09if(mode == UDP) `7B
  391. X`09`09if((Socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) `7B
  392. X`09`09`09perror("Can't create UDP local socket");
  393. X`09`09`09return;
  394. X`09`09`7D
  395. X`09`7D else `7B
  396. X`09`09if((Socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) `7B
  397. X`09`09`09perror("Can't create TCP local socket");
  398. X`09`09`09return;
  399. X`09`09`7D
  400. X`09`7D
  401. X
  402. X/* Create the connect structure */
  403. X`09SocketName.sin_family = (AF_INET);
  404. X`09SocketName.sin_port = htons(ISEND_PORT);
  405. X`09SocketName.sin_addr = htonl(InternetAddress);
  406. X`09for(i = 0; i < 8; i++)
  407. X`09`09(SocketName.sin_zero)`5Bi`5D = 0;`09/* Must be zero */
  408. X
  409. X/* If it is UDP then simply send the message */
  410. X`09if(mode == UDP) `7B
  411. X`09`09if(sendto(Socket, line, size, 0, &SocketName, sizeof(SocketName)) == -
  412. V1) `7B
  413. X`09`09`09perror("Can't send UDP message");
  414. X`09`09`7D
  415. X`09`09else `7B
  416. X`09`09`09/* the other side must confirm it by echoing the message */
  417. X`09`09`09printf("Waiting for confirmation...");
  418. X`09`09`09i = sizeof(SocketName);
  419. X`09`09`09if((size = recvfrom(Socket, line, sizeof line, 0,
  420. X`09`09`09    &SocketName, &i)) <= 0)
  421. X`09`09`09`09perror("Recvfrom");
  422. X`09`09`09else `7B`09/* Ignore what we got back */
  423. X`09`09`09`09printf(" OK\n");
  424. X`09`09`09`7D
  425. X`09`09`7D
  426. X`09`09close(Socket);
  427. X`09`7D
  428. X`09else `7B
  429. X/* TCP - Create a connection and send the message to there */
  430. X`09`09printf("Connecting...");
  431. X`09`09if(connect(Socket, &SocketName, sizeof(SocketName)) == 0) `7B
  432. X`09`09`09if(send(Socket, line, size, 0) > 0)
  433. X`09`09`09`09printf("Sent.\n");
  434. X`09`09`09else
  435. X`09`09`09`09perror("Can't send command");
  436. X`09`09`7D
  437. X`09`09else
  438. X`09`09`09perror("Can't connect");
  439. X`09`09close(Socket);
  440. X`09`7D
  441. X`7D
  442. $ CALL UNPACK ISEND.C;41 760638621
  443. $ create 'f'
  444. X1 ISEND`0D`0A
  445. X       ISEND is a program used to send one line interactive  message  to`0D`
  446. V0A
  447. X  another  user  on an InterNet host that supports this protocol.  It is`0D`
  448. V0A
  449. X  similar to the  BITnet's  TELL  (or  SEND/MESSAGE)  but  it  uses  the`0D`
  450. V0A
  451. X  InterNet  protocols rather than the NJE one (thus the hosts accessible`0D`
  452. V0A
  453. X  by it are usually different).  It can be  also  thought  as  the  Unix`0D`
  454. V0A
  455. X  WRITE command but not limited to the same host.`0D`0A
  456. X       Note that if the user is not logged-on at the time you  send  the`0D`
  457. V0A
  458. X  message you get no indication about it and the message is lost.  Thus,`0D`
  459. V0A
  460. X  use the FINGER command first  to  check  whether  the  other  side  is`0D`
  461. V0A
  462. X  logged-on.`0D`0A
  463. X`0D`0A
  464. X       The command's format is either:`0D`0A
  465. X`0D`0A
  466. X       $ ISEND  ADDRESS  text`0D`0A
  467. X`0D`0A
  468. X  in this case an unreliable protocol is used and the program is waiting`0D`
  469. V0A
  470. X  for a confirmation from the other side.  If no confirmation arrives in`0D`
  471. V0A
  472. X  a reasonable time (30-60 seconds) you should abort it.`0D`0A
  473. X`0D`0A
  474. X       A different method is:`0D`0A
  475. X`0D`0A
  476. X       $ ISEND  ADDRESS`0D`0A
  477. X`0D`0A
  478. X  Now you'll be propmted for the text line  by  line.   Each  line  will`0D`
  479. V0A
  480. X  generate a new connection to the other host using a reliable protocol.`0D`
  481. V0A
  482. X`0D`0A
  483. X       Incoming messages will appear on your screen with a message:`0D`0A
  484. X`0D`0A
  485. X       #### InterNet message from host xxxxx ####`0D`0A
  486. X`0D`0A
  487. X  Note that only the sending host can be identified  correctly  and  the`0D`
  488. V0A
  489. X  username can not be authenticated (thus it might be incorrect).`0D`0A
  490. X2 Examples`0D`0A
  491. X       In order to send a message using  unreliable  protocol  (UDP)  to`0D`
  492. V0A
  493. X  user XYZ on host X.Y.EDU issue the command:`0D`0A
  494. X`0D`0A
  495. X       $ ISEND XYZ@X.Y.EDU This is a test from Jerusalem`0D`0A
  496. X`0D`0A
  497. X  and in order to send a message to user OOO on  node  KUKURIKU  at  our`0D`
  498. V0A
  499. X  university using a reliable protocol (TCP) use the command:`0D`0A
  500. X`0D`0A
  501. X       $ ISEND OOO@KUKURIKU`0D`0A
  502. X       OOO@KUKURIKU:  this is another test`0D`0A
  503. X       OOO@KUKURIKU:  (hit <cr> to exit it)`0D`0A
  504. X`0D`0A
  505. X  Arriving messages to us will look like:`0D`0A
  506. X`0D`0A
  507. X       #### InterNet message from host KUKURIKU ####`0D`0A
  508. X       OOO@KUKURIKU:  This a test message...`0D`0A
  509. X`0D`0A
  510. X  Note:  Only the hostname at the first line is reliable.   The  address`0D`
  511. V0A
  512. X  at the second line can be forged thus it should not be trusted.`0D`0A
  513. $ CALL UNPACK ISEND.HLP;1 6514567
  514. $ create 'f'
  515. XTWG$TCP:`5BNETDIST.LIB`5DTWGLIB.OLB /LIB
  516. XSYS$SHARE:VAXCRTL.EXE /SHARE
  517. $ CALL UNPACK ISEND.OPT;2 2054710556
  518. $ create 'f'
  519. X.LOWER CASE
  520. X.RIGHT MARGIN 72
  521. X.NOPAG
  522. X.LEFT MARGIN +2
  523. X.INDENT -2
  524. X1#`5E`5EISEND\\
  525. X.PARAGRAPH 5,0
  526. X`5E`5EISEND\\ IS A PROGRAM USED TO SEND ONE LINE INTERACTIVE MESSAGE TO ANOT
  527. VHER
  528. XUSER ON AN `5EINTER`5ENET HOST THAT SUPPORTS THIS PROTOCOL. `5EIT IS SIMILAR
  529. V TO
  530. XTHE `5E`5EBIT\\NET'S `5E`5ETELL\\ (OR `5E`5ESEND/MESSAGE\\) BUT IT USES THE
  531. V `5EINTER`5ENET
  532. XPROTOCOLS RATHER THAN THE `5E`5ENJE\\ ONE (THUS THE HOSTS ACCESSIBLE BY IT A
  533. VRE
  534. XUSUALLY DIFFERENT). `5EIT CAN BE ALSO THOUGHT AS THE `5EUNIX `5E`5EWRITE\\ C
  535. VOMMAND
  536. XBUT NOT LIMITED TO THE SAME HOST.
  537. X.PARAGRAPH
  538. X`5ENOTE THAT IF THE USER IS NOT LOGGED-ON AT THE TIME YOU SEND THE MESSAGE Y
  539. VOU
  540. XGET NO INDICATION ABOUT IT AND THE MESSAGE IS LOST. `5ETHUS, USE THE `5E`5EF
  541. VINGER\\
  542. XCOMMAND FIRST TO CHECK WHETHER THE OTHER SIDE IS LOGGED-ON.
  543. X.BLANK
  544. X.PARAGRAPH
  545. X`5ETHE COMMAND'S FORMAT IS EITHER:
  546. X.BLANK
  547. X.INDENT +5
  548. X`5E`5E$#ISEND##`5EADDRESS\\##TEXT
  549. X.BLANK
  550. XIN THIS CASE AN UNRELIABLE PROTOCOL IS USED AND THE PROGRAM IS WAITING FOR
  551. XA CONFIRMATION FROM THE OTHER SIDE. `5EIF NO CONFIRMATION ARRIVES IN A REASO
  552. VNABLE
  553. XTIME (30-60 SECONDS) YOU SHOULD ABORT IT.
  554. X.BLANK
  555. X.PARAGRAPH
  556. X`5EA DIFFERENT METHOD IS:
  557. X.BLANK
  558. X.INDENT +5
  559. X`5E`5E$#ISEND##ADDRESS\\
  560. X.BLANK
  561. X`5ENOW YOU'LL BE PROPMTED FOR THE TEXT LINE BY LINE. `5EEACH LINE WILL GENER
  562. VATE
  563. XA NEW CONNECTION TO THE OTHER HOST USING A RELIABLE PROTOCOL.
  564. X.BLANK
  565. X.PARAGRAPH
  566. X`5EINCOMING MESSAGES WILL APPEAR ON YOUR SCREEN WITH A MESSAGE:
  567. X.BLANK
  568. X.INDENT 5
  569. X_#_#_#_# `5EINTER`5ENET MESSAGE FROM HOST XXXXX  _#_#_#_#
  570. X.BLANK
  571. X`5ENOTE THAT ONLY THE SENDING HOST CAN BE IDENTIFIED CORRECTLY AND THE USERN
  572. VAME
  573. XCAN NOT BE AUTHENTICATED (THUS IT MIGHT BE INCORRECT).
  574. X.INDENT -2
  575. X2#`5EEXAMPLES
  576. X.PARAGRAPH
  577. X`5EIN ORDER TO SEND A MESSAGE USING UNRELIABLE PROTOCOL (`5EU`5ED`5EP) TO US
  578. VER `5E`5EXYZ\\
  579. XON HOST `5E`5EX.Y.EDU\\ ISSUE THE COMMAND:
  580. X.BLANK
  581. X.INDENT +5
  582. X`5E`5E$#ISEND XYZ@X.Y.EDU\\ `5ETHIS IS A TEST FROM `5EJERUSALEM
  583. X.BLANK
  584. XAND IN ORDER TO SEND A MESSAGE TO USER `5E`5EOOO\\ ON NODE `5E`5EKUKURIKU\\
  585. V AT OUR
  586. XUNIVERSITY USING A RELIABLE PROTOCOL (`5E`5ETCP\\) USE THE COMMAND:
  587. X.BLANK
  588. X.INDENT +5
  589. X`5E`5E$#ISEND OOO@KUKURIKU
  590. X.INDENT +5
  591. XOOO@KUKURIKU: \\THIS IS ANOTHER TEST
  592. X.INDENT +5
  593. X`5E`5EOOO@KUKURIKU:\\ (HIT _<CR_> TO EXIT IT)
  594. X.BLANK
  595. X`5EARRIVING MESSAGES TO US WILL LOOK LIKE:
  596. X.BLANK
  597. X.INDENT +5
  598. X_#_#_#_# `5EINTER`5ENET MESSAGE FROM HOST `5E`5EKUKURIKU\\ _#_#_#_#
  599. X.INDENT +5
  600. X`5E`5EOOO@KUKURIKU:\\ `5ETHIS A TEST MESSAGE...
  601. X.BLANK
  602. X`5ENOTE: `5EONLY THE HOSTNAME AT THE FIRST LINE IS RELIABLE. `5ETHE ADDRESS
  603. V AT THE
  604. XSECOND LINE CAN BE FORGED THUS IT SHOULD NOT BE TRUSTED.
  605. $ CALL UNPACK ISEND.RNH;5 1516222054
  606. $ create 'f'
  607. X/* ISENDd.C`09V2.0
  608. X `7C  This program was written at the Hebrew University and is given for a p
  609. Vublic
  610. X `7C use as long as it is used for non-profit interests. The Hebrew universi
  611. Vty
  612. X `7C is not responsible for any damage that might be caused due to use or mi
  613. Vs-use
  614. X `7C of this software. It is given as-is with no waranty.
  615. X `7C
  616. X `7C   This is the daemon which should run at the background to receive mess
  617. Vages
  618. X `7C to local users and send them. It can be compiled either on Unix or VMS
  619. V with
  620. X `7C MultiNet. On IBM-AIX the compilation variable "unix" must be defined.
  621. X `7C
  622. X `7C Modified: 11-Aug-1992
  623. X `7C           Jim Gerland (JRG)
  624. X `7C           University at Buffalo
  625. X `7C           Added #ifdefs for Multinet & Wollongong
  626. X `7C
  627. X `7C On VMS it should be linked with the command:
  628. X `7C $ LINK /EXE=ISENDD.EXE ISENDD.OBJ,VMS_BROADCAST.OBJ,ISEND.OPT/OPTION
  629. X `7C and define it as a foreign DCL command.
  630. X `7C
  631. X `7C and on Unix:
  632. X `7C % cc -o isendd isendd.c unix_brdcst.c
  633. X `7C and run it as a detached process.
  634. X `7C
  635. X `7C  When receiving a message all control characters are stripped from it a
  636. Vnd
  637. X `7C it is then broadcasted to the user.
  638. X `7C
  639. X `7C  Note: MultiNet does not support the Select() function. Hence, this mod
  640. Vule
  641. X `7C is a total-mess in order to be compatible with Unix and VMS at once...
  642. X `7C
  643. X `7C  We can receive in parallel up to 32 TCP messages (TCP messages can com
  644. Ve in
  645. X `7C parts so we must keep a structure for each one).
  646. X `7C
  647. X `7C V2.0 - Accept format of RFC-1312 - simply ignore the extra fields.
  648. X */
  649. X#include <stdio.h>
  650. X#ifdef unix
  651. X#include <sys/types.h>
  652. X#include <sys/socket.h>
  653. X#include <netdb.h>
  654. X#include <sys/file.h>
  655. X#include <sys/ioctl.h>
  656. X#endif
  657. X
  658. X#ifdef MULTINET
  659. X#include "multinet_root:`5Bmultinet.include.sys`5Dtypes.h"
  660. X#include "multinet_root:`5Bmultinet.include.sys`5Dsocket.h"
  661. X#include "multinet_root:`5Bmultinet.include.netinet`5Din.h"
  662. X#include <stdio.h>
  663. X#include "multinet_root:`5Bmultinet.include`5Dnetdb.h"
  664. X#include "multinet_root:`5Bmultinet.include.vms`5Dinetiodef.h"
  665. X/* Multinet uses different naming in order to not clash with C routines: */
  666. X#define`09close`09socket_close
  667. X#define`09write`09socket_write
  668. X#define`09read`09socket_read
  669. X#define`09perror`09socket_perror
  670. X#endif /* MULTINET */
  671. X
  672. X#ifdef WINTCP /* JRG 11-Aug-1992 */
  673. X#include "twg$tcp:`5Bnetdist.include.sys`5Dtypes.h"
  674. X#include "twg$tcp:`5Bnetdist.include.sys`5Dsocket.h"
  675. X#include "twg$tcp:`5Bnetdist.include.netinet`5Din.h"
  676. X#include "twg$tcp:`5Bnetdist.include`5Dnetdb.h"
  677. X#endif /* WINTCP */
  678. X
  679. X#define`09LINESIZE`091024`09`09/* Our buffer size */
  680. X#define ISEND_PORT`0918`09`09/* UDP and TCP port 18 */
  681. X#define`09MAX_SESSIONS`0932`09`09/* Maximum number of concurrent TCP connect
  682. Vions open */
  683. X
  684. X#define`09UDP`090
  685. X#define`09TCP`091
  686. X
  687. Xchar`09LocalhostName`5B1024`5D;
  688. X
  689. X/* The sockaddr structure: */
  690. Xstruct sockaddr_in `7B
  691. X`09short`09`09sin_family;`09/* family */
  692. X`09unsigned short`09sin_port;`09/* port number */
  693. X`09unsigned long`09sin_addr;`09/* Internet address */
  694. X`09char`09`09sin_zero`5B8`5D;`09/* unused, must be 0 */
  695. X`7D;
  696. X
  697. X/* For TCP connections: */
  698. Xint`09TCPchannels`5BMAX_SESSIONS`5D,`09/* The TCP channels opened */
  699. X`09TCPipAddress`5BMAX_SESSIONS`5D,`09/* The IP address of sender */
  700. X`09TCPsizeRead`5BMAX_SESSIONS`5D;`09/* How much data we read already */
  701. Xchar`09TCPmessages`5BMAX_SESSIONS`5D`5BLINESIZE`5D;
  702. Xchar`09Message`5BLINESIZE`5D;`09`09/* Received message. Must be here for VMS
  703. V async IO */
  704. X
  705. X#ifndef unix
  706. X/* VMS does async IO and we have to keep some variables accessible by all ro
  707. Vutines */
  708. X`09short`09TCPiosb`5BMAX_SESSIONS`5D`5B4`5D,
  709. X`09`09UDPiosb`5B4`5D;
  710. X`09int`09FromLength;`09/* Length of data is FromSocket struct */
  711. X`09int`09UDPsocket;
  712. X`09struct`09sockaddr_in`09FromSocket;`09/* Fill here the sender's info */
  713. X#endif
  714. X
  715. X
  716. X/*
  717. X `7C Create the local sockets, bind them and then loop inside Select() for
  718. X `7C incoming data.
  719. X */
  720. Xmain()
  721. X`7B
  722. X`09int`09i, fd, TCPsocket,`09/* Socket descriptors */
  723. X`09`09status, `09`09/* Sockets on which we have read pending */
  724. X`09`09TableWidth;`09`09/* for Select */
  725. X`09int`09UDPsocket;
  726. X`09fd_set`09ReadFds;`09`09/* For Select */
  727. X`09struct`09sockaddr_in`09TCPsocketname, UDPsocketname;
  728. X
  729. X/* Create and bind local sockets */
  730. X`09UDPsocket = socket(AF_INET, SOCK_DGRAM, 0);
  731. X        TCPsocket = socket(AF_INET, SOCK_STREAM, 0);
  732. X`09if((UDPsocket == -1) `7C`7C (TCPsocket == -1)) `7B
  733. X`09`09printf("Can't create local socket.\n"); exit(1);
  734. X`09`7D
  735. X
  736. X`09TCPsocketname.sin_family = UDPsocketname.sin_family = AF_INET;
  737. X`09TCPsocketname.sin_port = UDPsocketname.sin_port = htons(ISEND_PORT);
  738. X`09TCPsocketname.sin_addr = UDPsocketname.sin_addr = 0;`09/* Local host */
  739. X`09if(bind(UDPsocket, &UDPsocketname, sizeof(UDPsocketname)) == -1) `7B
  740. X`09`09perror("UDP socket bind"); exit(1);
  741. X`09`7D
  742. X`09if(bind(TCPsocket, &TCPsocketname, sizeof(TCPsocketname)) == -1) `7B
  743. X                perror("TCP socket bind"); exit(1);
  744. X`09`7D
  745. X
  746. X/* Listen on the TCP socket (UDP have no Listen facility) */
  747. X`09if(listen(TCPsocket, 5) == -1) `7B
  748. X`09`09perror("TCP listen"); exit(1);
  749. X`09`7D
  750. X
  751. X/* Fork if we are a unix system */
  752. X#ifdef unix
  753. X `09if(fork())          /* Move to the background automatically */
  754. X `09`09exit(0);
  755. X `09setpgrp(0, getpid());    /* Set a new process group. */
  756. X `09if((fd = open("/dev/tty", O_RDWR)) >= 0)  `7B
  757. X `09`09ioctl(fd, TIOCNOTTY, 0);     /* Disconnect from terminal */
  758. X `09`09close(fd);
  759. X `09`7D
  760. X `09chdir("/");     /* To prevent "Mount device busy" messages */
  761. X#endif
  762. X
  763. X/* Clear the TCP sessions array. A size of -1 signals a free entry */
  764. X`09for(i = 0; i < MAX_SESSIONS; i++)
  765. X`09`09TCPsizeRead`5Bi`5D = -1;
  766. X
  767. X/* Now, wait for a coming call */
  768. X/* Unix - Wait in select for a call or data for an opened connection */
  769. X`09for(;;) `7B
  770. X#ifndef WINTCP /* JRG 11-Aug-1992 */
  771. X`09`09TableWidth = getdtablesize();`09/* Get descriptors table size */
  772. X#endif
  773. X`09`09FD_ZERO(&ReadFds);`09/* Clear all FDs */
  774. X`09`09FD_SET(TCPsocket, &ReadFds);`09/* Set the channels we want info on */
  775. X`09`09FD_SET(UDPsocket, &ReadFds);
  776. X`09`09/* Set the FD's of opened TCP connections */
  777. X`09`09for(i = 0; i < MAX_SESSIONS; i++)
  778. X`09`09`09if(TCPsizeRead`5Bi`5D >= 0)
  779. X`09`09`09`09FD_SET(TCPchannels`5Bi`5D, &ReadFds);
  780. X
  781. X/* Wait in select() untill something to do (last parameter NULL signals it t
  782. Vo
  783. X   block untill there is something to read) */
  784. X`09`09if(select(TableWidth, &ReadFds, NULL, NULL, NULL) == -1) `7B
  785. X`09`09`09/* Error in select */
  786. X`09`09`09perror("Select"); exit(1);
  787. X`09`09`7D
  788. X/* Something have to be read: */
  789. X`09`09if(FD_ISSET(TCPsocket, &ReadFds))
  790. X`09`09`09accept_tcp_connection(TCPsocket);
  791. X`09`09/* Check the FD's of opened TCP connections */
  792. X`09`09for(i = 0; i < MAX_SESSIONS; i++)
  793. X`09`09`09if(FD_ISSET(TCPchannels`5Bi`5D, &ReadFds))
  794. X`09`09`09`09read_tcp_data(i);
  795. X`09`09if(FD_ISSET(UDPsocket, &ReadFds))
  796. X`09`09`09read_udp_data(UDPsocket);
  797. X`09`7D
  798. X`7D
  799. X
  800. X
  801. X/*
  802. X `7C Some data came over the UDP channel - read the packet, decompose it, an
  803. Vd
  804. X `7C send to user. Then send back the same message to sender
  805. X */
  806. Xread_udp_data(UDPsocket)
  807. Xint`09UDPsocket;
  808. X`7B
  809. X`09int`09MessageSize,
  810. X`09`09ProtocolVersion,
  811. X`09`09FromLength;`09/* Length of data is FromSocket struct */
  812. X`09struct`09sockaddr_in`09FromSocket;`09/* Fill here the sender's info */
  813. X`09char`09ReplyBuffer`5BLINESIZE`5D;
  814. X
  815. X/* On Unix we have to read the message now */
  816. X`09FromLength = sizeof(struct sockaddr_in);`09/* Have to be initialized */
  817. X`09MessageSize = recvfrom(UDPsocket, Message, sizeof(Message), 0,
  818. X`09`09`09       &FromSocket, &FromLength);
  819. X
  820. X`09if((ProtocolVersion = handle_message(Message, MessageSize,
  821. X`09    FromSocket.sin_addr)) != 0) `7B
  822. X/* Send the a message back to sender telling him we got it */
  823. X`09`09if(ProtocolVersion == 1)`09/* Old version */
  824. X`09`09`09if(sendto(UDPsocket, Message, MessageSize, 0, &FromSocket, FromLeng
  825. Vth) <= 0)
  826. X`09`09`09`09perror("Sendto");
  827. X`09`09else `7B
  828. X`09`09`09strcpy(ReplyBuffer, "+OK");
  829. X`09`09`09if(sendto(UDPsocket, ReplyBuffer, strlen(ReplyBuffer) + 1, 0,
  830. X`09`09`09`09&FromSocket, FromLength) <= 0)
  831. X`09`09`09`09`09perror("Sendto");
  832. X`09`09`7D
  833. X`09`7D
  834. X`7D
  835. X
  836. X
  837. X/*
  838. X `7C A connection has been requested. Accept it and set the TCP arrays accor
  839. Vdingly.
  840. X `7C On VMS we simply wait here inside the ACCEPT untill a new connection ar
  841. Vrive.
  842. X `7C When it is accepted we queue an IO for it and the rest of the work is d
  843. Vone
  844. X `7C in ASTs (so we can sleep again in ACCEPT).
  845. X */
  846. Xaccept_tcp_connection(TCPsocket)
  847. Xint`09TCPsocket;
  848. X`7B
  849. X`09int`09i, FromLength;`09/* Length pf FromSocket */
  850. X`09struct`09sockaddr_in`09FromSocket;
  851. X
  852. X/* Find an empty slot (REadSize = -1) */
  853. X`09for(i = 0; i < MAX_SESSIONS; i++)
  854. X`09`09if(TCPsizeRead`5Bi`5D == -1) break;`09/* Free entry */
  855. X`09if(i == MAX_SESSIONS)`09/* No free entry found */
  856. X`09`09return;`09/* Can't handle it. Hopefully we never get to here... */
  857. X
  858. X/* Accept it */
  859. X`09FromLength = sizeof(FromSocket);
  860. X`09TCPchannels`5Bi`5D = accept(TCPsocket, &FromSocket, &FromLength);
  861. X`09if(TCPchannels`5Bi`5D == -1) `7B`09/* Failed */
  862. X`09`09return;
  863. X`09`7D
  864. X
  865. X/* Accepted correctly - mark as occiupied and save the IP address of sender
  866. V */
  867. X`09TCPsizeRead`5Bi`5D = 0;`09/* Mark it as occiupied and no data yet */
  868. X`09TCPipAddress`5Bi`5D = FromSocket.sin_addr;
  869. X/* Accept done. Now wait for data */
  870. X`7D
  871. X
  872. X
  873. X/*
  874. X `7C Some data arrived from the TCP connection. Append it to our buffer and
  875. V wait
  876. X `7C for more data. If we read 0 bytes then this is a signal that the other
  877. V side
  878. X `7C closed the connection. In this case we should have now a full message.
  879. X */
  880. Xread_tcp_data(Connection)
  881. Xint`09Connection;`09/* Connection number in our arrays */
  882. X`7B
  883. X`09int`09size, ProtocolVersion;
  884. X`09char`09ReplyBuffer`5BLINESIZE`5D;
  885. X
  886. X/* Compute the size of area left in buffer for this connection */
  887. X`09size = LINESIZE - TCPsizeRead`5BConnection`5D;
  888. X`09if(size < 0) `7B`09/* Some error; hopefully will never happen */
  889. X`09`09close(TCPchannels`5BConnection`5D);
  890. X`09`09TCPsizeRead`5BConnection`5D = -1;`09/* Mark it as free */
  891. X`09`09return;
  892. X`09`7D
  893. X
  894. X`09size = recv(TCPchannels`5BConnection`5D,
  895. X`09`09&(TCPmessages`5BConnection`5D`5BTCPsizeRead`5BConnection`5D`5D),
  896. X`09`09size, 0);
  897. X
  898. X`09if(size < 0) `7B
  899. X`09`09close(TCPchannels`5BConnection`5D);
  900. X`09`09TCPsizeRead`5BConnection`5D = -1;`09/* Mark it as free */
  901. X`09`09return;
  902. X`09`7D
  903. X
  904. X/* If the size is zero then the other party closed the connection and we hav
  905. Ve
  906. X   a full message */
  907. X`09if(size == 0) `7B
  908. X`09`09if((ProtocolVersion = handle_message(TCPmessages`5BConnection`5D, TCPs
  909. VizeRead`5BConnection`5D,
  910. X`09`09`09TCPipAddress`5BConnection`5D)) != 0) `7B
  911. X/* Send the a message back to sender telling him we got it */
  912. X`09`09`09if(ProtocolVersion > 1) `7B
  913. X`09`09`09`09strcpy(ReplyBuffer, "+OK");
  914. X`09`09`09`09if(send(TCPchannels`5BConnection`5D, ReplyBuffer,
  915. X`09`09`09`09`09strlen(ReplyBuffer) + 1, 0) <= 0)
  916. X`09`09`09`09`09perror("Send");
  917. X`09`09`09`7D
  918. X`09`09`7D
  919. X`09`09close(TCPchannels`5BConnection`5D);
  920. X`09`09TCPsizeRead`5BConnection`5D = -1;
  921. X`09`09return;
  922. X`09`7D
  923. X
  924. X/* Non-zero size - increase count */
  925. X`09TCPsizeRead`5BConnection`5D += size;
  926. X`7D
  927. X
  928. X
  929. X/*
  930. X `7C Common path to UDP and TCP - Decode the message and send it to the user
  931. V.
  932. X `7C Return zero if some error, 1 if ok.
  933. X */
  934. Xhandle_message(Message, MessageSize, IPaddress)
  935. Xchar`09*Message;`09/* The message buffer */
  936. Xunsigned int`09MessageSize,`09/* How much was read */
  937. X`09IPaddress;`09/* IP address of sending host */
  938. X`7B
  939. X`09int`09size;
  940. X`09char`09ToUser`5BLINESIZE`5D,`09/* USername to send to */
  941. X`09`09FromHost`5BLINESIZE`5D;`09/* Host name that sent us this message */
  942. X`09struct`09hostent`09*HostEnt;
  943. X
  944. X`09if(MessageSize <= 0) return;`09/* Some error */
  945. X`09Message`5BMessageSize`5D = '\0';`09/* Delimit it for C functions to work
  946. V correctly */
  947. X
  948. X/* First - get the hostname of the sender */
  949. X`09if((HostEnt = gethostbyaddr(&IPaddress, sizeof(long), AF_INET)) == NULL)
  950. X`09`09/* Can't get it - use numeric address */
  951. X`09`09sprintf(FromHost, "%d.%d.%d.%d",
  952. X`09`09`09((ntohl(IPaddress) >> 24) & 0xff),
  953. X`09`09`09((ntohl(IPaddress) >> 16) & 0xff),
  954. X`09`09`09((ntohl(IPaddress) >> 8) & 0xff),
  955. X`09`09`09((ntohl(IPaddress)) & 0xff));
  956. X`09else`09strcpy(FromHost, HostEnt->h_name);
  957. X
  958. X/* Check the protocol version */
  959. X`09if((*Message != 'A') && (*Message != 'B'))
  960. X`09`09return 0;`09/* Different version - ignore it */
  961. X`09strcpy(ToUser, &Message`5B1`5D);
  962. X`09if(*ToUser == '\0')`09/* No sepcific user - ignore */
  963. X`09`09return 0;
  964. X`09size = strlen(Message);`09`09/* THe next byte after username */
  965. X`09if(size >= MessageSize) return 0;`09/* Too short message */
  966. X`09size++;`09`09/* First character of terminal name */
  967. X`09size += (strlen(&Message`5Bsize`5D) + 1);`09/* Ignore terminal name */
  968. X        if(size >= MessageSize) return 0; /* Too short message */
  969. X
  970. X`09broadcast_user(ToUser, &Message`5Bsize`5D, FromHost);
  971. X`09return(*Message - '@');`09`09/* Return the version number */
  972. X`7D
  973. X
  974. X/*
  975. X `7C remove all controls, Format and send the message to the terminal.
  976. X */
  977. Xbroadcast_user(ToUser, MessageText, FromHost)
  978. Xchar`09*ToUser, *MessageText, *FromHost;
  979. X`7B
  980. X`09unsigned char`09*p;
  981. X`09char`09Message`5BLINESIZE`5D;
  982. X
  983. X/* Remove all controls */
  984. X        for(p = (unsigned char *)MessageText; *p != '\0'; *p++)
  985. X                if((*p < ' ') `7C`7C (*p > '\176')) *p = ' ';
  986. X
  987. X/* Start the message with a message who sent it and append CR LF to it: */
  988. X`09sprintf(Message, "\007\r\n   #### InterNet message from host %s ####\r\n"
  989. V,
  990. X`09`09FromHost);
  991. X`09strcat(Message, MessageText);`09/* Get the message text */
  992. X`09strcat(Message, "\r\n");
  993. X`09send_user(ToUser, Message);
  994. X`7D
  995. $ CALL UNPACK ISENDD.C;48 1631354280
  996. $ create 'f'
  997. X# makefile for isend & isendd
  998. X
  999. Xcflags = /NOLIST /DEFINE=WINTCP
  1000. X
  1001. Xisend : isend.exe isendd.exe
  1002. X
  1003. Xisend.exe : isend.obj
  1004. X   link /exe=isend.exe isend.obj,isend.opt /opt
  1005. X
  1006. Xisend.obj : isend.c
  1007. X   cc $(cflags) /obj=isend.obj isend.c
  1008. X
  1009. Xisendd.exe : isendd.obj vms_broadcast.obj
  1010. X   link /exe=isendd.exe isendd.obj,vms_broadcast.obj,isend.opt /opt
  1011. X
  1012. Xisendd.obj : isendd.c
  1013. X   cc $(cflags) /obj=isendd.obj isendd.c
  1014. X
  1015. Xvms_broadcast.obj : vms_broadcast.c
  1016. X   cc $(cflags) /obj=vms_broadcast.obj vms_broadcast.c
  1017. X
  1018. $ CALL UNPACK MAKEFILE.;5 103375806
  1019. $ create 'f'
  1020. XMULTINET:MULTINET_SOCKET_LIBRARY/SHARE
  1021. XSYS$SHARE:VAXCRTL/SHARE
  1022. $ CALL UNPACK MULTINET.OPT;2 1662129023
  1023. $ create 'f'
  1024. X$ RUN /DETACH /INPUT=NL: -
  1025. X      /OUTPUT=DISK$USERDISK4:`5BACS0.UTIL.MSP`5DISEND.OUT -
  1026. X      /ERROR=DISK$USERDISK4:`5BACS0.UTIL.MSP`5DISEND.ERR -
  1027. X      /PROCESS_NAME="ISEND_task" -
  1028. X      /PRIV=(NOALL,TMPMBX,NETMBX,OPER,SYSPRV,CMKRNL) -
  1029. X      DISK$USERDISK4:`5BACS0.UTIL.MSP`5DISENDD.EXE
  1030. $ CALL UNPACK START-ISEND-SERVER.COM;3 1415273604
  1031. $ create 'f'
  1032. X/* UNIX_BRDCST.C `09V1.0
  1033. X `7C  This program was written at the Hebrew University and is given for a p
  1034. Vublic
  1035. X `7C use as long as it is used for non-profit interests. The Hebrew universi
  1036. Vty
  1037. X `7C is not responsible for any damage that might be caused due to use or mi
  1038. Vs-use
  1039. X `7C of this software. It is given as-is with no waranty.
  1040. X `7C
  1041. X `7C  This module is used on Unix systems to broadcast a message to a given
  1042. V user
  1043. X `7C on all terminals he is logged-on. This module was contributed by Eitan
  1044. X `7C Mizrotsky.
  1045. X*/
  1046. X
  1047. X#include  <stdio.h>
  1048. X#include  <pwd.h>
  1049. X#include  <sys/types.h> /* `5Bmea`5D Needed in some systems for <utmp.h> */
  1050. X#include  <utmp.h>
  1051. X#include  <sys/fcntl.h> /* `5Bmea`5D Needed in some systems. */
  1052. X#include  <sys/file.h>
  1053. X#include  <sys/stat.h>  /* `5Bmea`5D Needed for mesg state analyse */
  1054. X
  1055. X
  1056. X#define UTMP    "/etc/utmp"
  1057. X
  1058. Xextern int errno;
  1059. X
  1060. X
  1061. X/*
  1062. X* Write the message msg to the user, on all ttys he is currently logged
  1063. X* in.
  1064. X* Returned value:
  1065. X* 0 in case of error, number of messages sent otherwise.
  1066. X* In case of error, errno can be examined.
  1067. X*/
  1068. Xsend_user(user, msg)
  1069. Xchar *user, *msg;
  1070. X`7B
  1071. X`09int cnt = 0, fdutmp;
  1072. X`09int ftty;
  1073. X`09char buf`5BBUFSIZ`5D;
  1074. X`09int i, m, n = (BUFSIZ / sizeof(struct utmp));
  1075. X`09int bufsiz = n * sizeof(struct utmp);
  1076. X`09char tty`5B16`5D;
  1077. X`09struct stat stats;
  1078. X
  1079. X`09for(cnt = 0; cnt < strlen(user); cnt++)
  1080. X`09`09if(user`5Bcnt`5D == ' ') `7B
  1081. X`09`09`09user`5Bcnt`5D = '\0'; break;
  1082. X`09`09`7D
  1083. X`09`09else if((user`5Bcnt`5D >= 'A') && (user`5Bcnt`5D <= 'Z'))
  1084. X`09`09`09user`5Bcnt`5D += ' ';  /* lowercasify */
  1085. X
  1086. X`09if((fdutmp = open(UTMP, O_RDONLY)) <= 0)  `7B
  1087. X`09`09return(0);
  1088. X`09`7D
  1089. X
  1090. X`09cnt = 0;
  1091. X
  1092. X`09while((m = read(fdutmp, buf, bufsiz)) > 0)  `7B
  1093. X`09`09m /= sizeof(struct utmp);
  1094. X`09`09for(i = 0; i < m; i++)   `7B
  1095. X/* IBM-RS6000 specific field: */
  1096. X#ifdef USER_PROCESS
  1097. X`09`09`09if(((struct utmp *)buf)`5Bi`5D.ut_type != USER_PROCESS) continue;
  1098. X#endif
  1099. X`09`09`09if(memcmp(user, ((struct utmp *)buf)`5Bi`5D.ut_name, strlen(user))
  1100. V != 0)
  1101. X`09`09`09`09continue;
  1102. X`09`09`09sprintf(tty, "/dev/%s", ((struct utmp *)buf)`5Bi`5D.ut_line);
  1103. X`09`09`09if((ftty = open(tty, O_WRONLY)) < 0)  `7B
  1104. X`09`09`09`09continue;  /* Some TTYs accept, some don't */
  1105. X`09`09`09`7D
  1106. X`09`09`09if(fstat(ftty,&stats)!=0 `7C`7C (stats.st_mode & 022)==0)`7B
  1107. X`09`09`09`09close(ftty); /* mesg -n! */
  1108. X`09`09`09`09continue;  /* Some TTYs accept, some don't */
  1109. X`09`09`09`7D
  1110. X`09`09`09if(write(ftty, msg, strlen(msg)) < strlen(msg))  `7B
  1111. X`09`09`09`09close(ftty);
  1112. X`09`09`09`09continue;  /* Some TTYs accept, some don't */
  1113. X`09`09`09`7D
  1114. X`09`09`09close(ftty);
  1115. X`09`09`09++cnt;
  1116. X`09`09`7D
  1117. X`09`7D
  1118. X`09close(fdutmp);
  1119. X
  1120. X`09return(cnt);
  1121. X`7D
  1122. $ CALL UNPACK UNIX_BRDCST.C;3 554798693
  1123. $ create 'f'
  1124. X/* VMS_BROADCAST.C`09V1.0
  1125. X `7C  This program was written at the Hebrew University and is given for a p
  1126. Vublic
  1127. X `7C use as long as it is used for non-profit interests. The Hebrew universi
  1128. Vty
  1129. X `7C is not responsible for any damage that might be caused due to use or mi
  1130. Vs-use
  1131. X `7C of this software. It is given as-is with no waranty.
  1132. X `7C
  1133. X `7C  This module broadcasts the messages to the user on all terminals he is
  1134. X `7C logged-in.
  1135. X */
  1136. X/* From STARTLET.MLB, module $BRKDEF: */
  1137. X#define`09BRK$C_USERNAME`092
  1138. X#define`09BRK$C_USER1`0932
  1139. X#define`09BRK$M_CLUSTER`092048
  1140. X
  1141. X#define`09LINESIZE`091024
  1142. X
  1143. X/* VMS string descriptor */
  1144. Xstruct DESC `7B
  1145. X`09short`09length, class;
  1146. X`09char`09*address;
  1147. X`7D;
  1148. X
  1149. X
  1150. X/*
  1151. X `7C  Given a user-name, find all terminals he is logged-in and send him
  1152. X `7C  the given message. We use 5 seconds timeout since this is the minimal
  1153. X `7C time allowed by VMS.
  1154. X `7C The function returns the number of terminals successfully notified.
  1155. X*/
  1156. Xint
  1157. Xsend_user(UserName, string)
  1158. Xchar`09*UserName, *string;
  1159. X`7B
  1160. X`09static struct`09DESC`09username, message;
  1161. X`09static char`09temp`5BLINESIZE`5D, *p;
  1162. X`09static short`09iosb`5B2`5D;
  1163. X`09static long`09sndtyp, reqid;
  1164. X`09long`09status;
  1165. X
  1166. X/* First - modify username to upper case for $BRKTHRU (can't handle lower
  1167. X   case) */
  1168. X`09strcpy(temp, UserName);
  1169. X`09for(p = temp; *p != '\0'; p++)
  1170. X`09`09if((*p >= 'a') && (*p <= 'z')) *p -= ' ';
  1171. X
  1172. X`09message.length = strlen(string);  message.address = string;`09/* Create a
  1173. V descriptor */
  1174. X`09username.length = strlen(temp); username.address = temp;
  1175. X`09sndtyp = BRK$C_USERNAME;`09/* Send by username */
  1176. X`09reqid = BRK$C_USER1;`09`09/* Type of message */
  1177. X`09status = sys$brkthruw((long)(0),
  1178. X`09`09&message, &username, sndtyp,
  1179. X`09`09iosb, (long)(0), (long)(BRK$M_CLUSTER), reqid,
  1180. X`09`09(long)(5),`09/* 5 seconds timeout */
  1181. X`09`09(long)(0), (long)(0));
  1182. X
  1183. X`09return (int)(iosb`5B1`5D);`09/* Return number of users informed */
  1184. X`7D
  1185. X
  1186. $ CALL UNPACK VMS_BROADCAST.C;7 420896704
  1187. $ create 'f'
  1188. XTWG$TCP:`5BNETDIST.LIB`5DTWGLIB.OLB /LIB
  1189. XSYS$SHARE:VAXCRTL.EXE /SHARE
  1190. $ CALL UNPACK WIN.OPT;3 2054710556
  1191. $ v=f$verify(v)
  1192. $ EXIT
  1193. --
  1194. Jim Gerland  - Consultant, Network User Support         University at Buffalo
  1195. Academic Services, Computing & Information Technology   Buffalo, NY 14260
  1196. 716.645.3557 Work                                       716.645.3734 FAX
  1197. gerland@ubvms.cc.buffalo.edu                            gerland@ubvms.bitnet
  1198.