home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / sources / misc / 4242 < prev    next >
Encoding:
Text File  |  1993-01-10  |  50.2 KB  |  1,699 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: amber@engin.umich.edu (Lee Liming)
  4. Subject: v34i100:  netuse - A Network Host Usage Monitoring System, Part02/06
  5. Message-ID: <1993Jan11.023512.25199@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 5efa2c021f556a71f14941e50201da4e
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. References: <csm-v34i099=netuse.203327@sparky.IMD.Sterling.COM>
  11. Date: Mon, 11 Jan 1993 02:35:12 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 1684
  14.  
  15. Submitted-by: amber@engin.umich.edu (Lee Liming)
  16. Posting-number: Volume 34, Issue 100
  17. Archive-name: netuse/part02
  18. Environment: UNIX, MS-DOS, OS/2, INET, MSC
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then feed it
  22. # into a shell via "sh file" or similar.  To overwrite existing files,
  23. # type "sh file -c".
  24. # Contents:  netuse/daemons/netuse.c netuse/daemons/netused.c
  25. #   netuse/lib/gethost.c
  26. # Wrapped by kent@sparky on Sun Jan 10 20:28:35 1993
  27. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  28. echo If this archive is complete, you will see the following message:
  29. echo '          "shar: End of archive 2 (of 6)."'
  30. if test -f 'netuse/daemons/netuse.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'netuse/daemons/netuse.c'\"
  32. else
  33.   echo shar: Extracting \"'netuse/daemons/netuse.c'\" \(20734 characters\)
  34.   sed "s/^X//" >'netuse/daemons/netuse.c' <<'END_OF_FILE'
  35. X/******************************************************************************
  36. X NETUSE.C - Network Host Use Monitor Server
  37. X
  38. X This program acts as a server, receiving periodic information from network
  39. X hosts concerning their current states.  It also accepts requests for 
  40. X information concerning these hosts, and makes the information available to
  41. X client machines.
  42. X
  43. X Lee Liming and Michael Neil, The Computer Aided Engineering Network
  44. X The University of Michigan
  45. X
  46. X Copyright (C) 1990, 1991, 1992 by the Regents of the University of Michigan.
  47. X
  48. X User agrees to reproduce said copyright notice on all copies of the software
  49. X made by the recipient.  
  50. X
  51. X All Rights Reserved. Permission is hereby granted for the recipient to make
  52. X copies and use this software for its own internal purposes only. Recipient of
  53. X this software may re-distribute this software outside of their own
  54. X institution. Permission to market this software commercially, to include this
  55. X product as part of a commercial product, or to make a derivative work for
  56. X commercial purposes, is explicitly prohibited.  All other uses are also
  57. X prohibited unless authorized in writing by the Regents of the University of
  58. X Michigan.
  59. X
  60. X This software is offered without warranty. The Regents of the University of
  61. X Michigan disclaim all warranties, express or implied, including but not
  62. X limited to the implied warranties of merchantability and fitness for any
  63. X particular purpose. In no event shall the Regents of the University of
  64. X Michigan be liable for loss or damage of any kind, including but not limited
  65. X to incidental, indirect, consequential, or special damages. 
  66. X******************************************************************************/
  67. X
  68. X#include <stdio.h>
  69. X#include <sys/types.h>
  70. X#include <sys/time.h>
  71. X#include <sys/socket.h>
  72. X#include <netinet/in.h>
  73. X#include <netdb.h>
  74. X#include <signal.h>
  75. X#include <setjmp.h>
  76. X#include <pwd.h>
  77. X#include <errno.h>
  78. X#if (defined(_AIX) || defined(apollo))
  79. X#include <sys/ioctl.h>
  80. X#else
  81. X#include <sys/termios.h>
  82. X#endif
  83. X
  84. X#include "../lib/protocol.h"
  85. X#include "../lib/netuse.h"
  86. X#include "../lib/config.h"
  87. X#include "../lib/variable.h"
  88. X
  89. X
  90. X/* #define DEBUG */
  91. X
  92. X
  93. Xextern long lTime;
  94. Xextern VARTABLE variables;
  95. X
  96. Xint sock;
  97. Xstruct sockaddr_in myname;
  98. Xjmp_buf jumpTimeout;
  99. Xlong lastCheck=0,lastSave=0,netuseStartTime;
  100. X
  101. X
  102. X#ifdef __STDC__
  103. Xint packetSend(USEREC *msg,struct sockaddr_in *dest)
  104. X#else
  105. Xint packetSend(msg,dest)
  106. XUSEREC *msg;
  107. Xstruct sockaddr_in *dest;
  108. X#endif
  109. X{
  110. X     u_char chk;
  111. X     int rv,count,i;
  112. X     PACKET out;
  113. X
  114. X     msg->load1=htons(msg->load1);
  115. X     msg->load2=htons(msg->load2);
  116. X     msg->load3=htons(msg->load3);
  117. X     msg->users=htons(msg->users);
  118. X     msg->console=htons(msg->console);
  119. X     msg->tmp=htonl(msg->tmp);
  120. X     msg->uid=htons(msg->uid);
  121. X     bcopy(msg,out,sizeof(PACKET));
  122. X     for (chk=0,i=1; i<PACKET_SIZE; i++)
  123. X          chk=(chk+out[i]) % 0xFF;
  124. X     out[0]=chk;
  125. X#ifdef DEBUG
  126. X     printf("Server sending:\n");
  127. X     printf("Opcode=%02x Retcode=%02x Ack=%02x Load1=%04x Load2=%04x Load3=%04x\n",
  128. X            msg->opcode,msg->retcode,msg->ack,ntohs(msg->load1),
  129. X            ntohs(msg->load2),ntohs(msg->load3));
  130. X     printf("Users=%04x Console=%04x Tmp=%08x Mach=%2x Model=%02x Chksum=%02x\n",
  131. X            ntohs(msg->users),ntohs(msg->console),ntohl(msg->tmp),
  132. X            msg->machine,msg->model,out[0]);
  133. X     printf("Data:");
  134. X     for (i=0; i<PACKET_SIZE; i++) {
  135. X          if (i && !(i % 16)) printf("\n     ");
  136. X          printf(" %02x",out[i]);
  137. X     }
  138. X     printf("\n");
  139. X#endif
  140. X     count=0;
  141. X     do {
  142. X          rv=sendto(sock,out,PACKET_SIZE,0,dest,sizeof(struct sockaddr_in));
  143. X          if (rv==(-1)) {
  144. X               perror("sendto");
  145. X               if (++count>SEND_RETRIES) return(RV_nBADSEND);
  146. X          }
  147. X     } while (rv!=PACKET_SIZE);
  148. X     return(RV_nOK);
  149. X}
  150. X
  151. X
  152. X#ifdef __STDC__
  153. Xint AlarmHandler(int sig)
  154. X#else
  155. Xint AlarmHandler(sig)
  156. Xint sig;
  157. X#endif
  158. X{
  159. X     longjmp(jumpTimeout,1);
  160. X     return(0);
  161. X}
  162. X
  163. X
  164. X#ifdef __STDC__
  165. Xint packetReceiveT(USEREC *msg,struct sockaddr_in *src)
  166. X#else
  167. Xint packetReceiveT(msg,src)
  168. XUSEREC *msg;
  169. Xstruct sockaddr_in *src;
  170. X#endif
  171. X{
  172. X     u_char chk;
  173. X     int i;
  174. X     PACKET in;
  175. X
  176. X     do {
  177. X          signal(SIGALRM,AlarmHandler);
  178. X          if (setjmp(jumpTimeout)!=0) return(RV_nTIMEOUT);
  179. X          alarm(TIMEOUT);
  180. X          i=sizeof(struct sockaddr_in);
  181. X          if (recvfrom(sock,in,PACKET_SIZE,0,src,&i)==(-1)) {
  182. X               perror("recvfrom");
  183. X               return(RV_nBADRECV);
  184. X          }
  185. X          alarm(0);
  186. X          signal(SIGALRM,SIG_DFL);
  187. X          bcopy(in,msg,sizeof(PACKET));
  188. X#ifdef DEBUG
  189. X          printf("Server received:\n");
  190. X          printf("Opcode=%02x Retcode=%02x Ack=%02x Load1=%04x Load2=%04x Load3=%04x\n",
  191. X                 msg->opcode,msg->retcode,msg->ack,ntohs(msg->load1),
  192. X                 ntohs(msg->load2),ntohs(msg->load3));
  193. X          printf("Users=%04x Console=%04x Tmp=%08x Mach=%02x Model=%02x Chksum=%02x\n",
  194. X                 ntohs(msg->users),ntohs(msg->console),ntohl(msg->tmp),
  195. X                 msg->machine,msg->model,in[0]);
  196. X          printf("Data:");
  197. X          for (i=0; i<PACKET_SIZE; i++) {
  198. X               if (i && !(i % 16)) printf("\n     ");
  199. X               printf(" %02x",in[i]);
  200. X          }
  201. X          printf("\n");
  202. X#endif
  203. X          for (chk=0,i=1; i<PACKET_SIZE; i++)
  204. X               chk=(chk+in[i]) % 0xFF;
  205. X     } while (chk!=msg->chksum);
  206. X     msg->load1=ntohs(msg->load1);
  207. X     msg->load2=ntohs(msg->load2);
  208. X     msg->load3=ntohs(msg->load3);
  209. X     msg->users=ntohs(msg->users);
  210. X     msg->console=ntohs(msg->console);
  211. X     msg->tmp=ntohl(msg->tmp);
  212. X     msg->uid=ntohs(msg->uid);
  213. X     return(RV_nOK);
  214. X}
  215. X
  216. X
  217. X#ifdef __STDC__
  218. Xint packetReceive(USEREC *msg,struct sockaddr_in *src)
  219. X#else
  220. Xint packetReceive(msg,src)
  221. XUSEREC *msg;
  222. Xstruct sockaddr_in *src;
  223. X#endif
  224. X{
  225. X     u_char chk;
  226. X     int i;
  227. X     PACKET in;
  228. X
  229. X     do {
  230. X          i=sizeof(struct sockaddr_in);
  231. X          if (recvfrom(sock,in,PACKET_SIZE,0,src,&i)==(-1)) {
  232. X               perror("recvfrom");
  233. X               return(RV_nBADRECV);
  234. X          }
  235. X          bcopy(in,msg,sizeof(PACKET));
  236. X#ifdef DEBUG
  237. X          printf("Server received:\n");
  238. X          printf("Opcode=%02x Retcode=%02x Ack=%02x Load1=%04x Load2=%04x Load3=%04x\n",
  239. X                 msg->opcode,msg->retcode,msg->ack,ntohs(msg->load1),
  240. X                 ntohs(msg->load2),ntohs(msg->load3));
  241. X          printf("Users=%04x Console=%04x Tmp=%08x Mach=%02x Model=%02x Chksum=%02x\n",
  242. X                 ntohs(msg->users),ntohs(msg->console),ntohl(msg->tmp),
  243. X                 msg->machine,msg->model,in[0]);
  244. X          printf("PACKET_SIZE=%d\n",PACKET_SIZE);
  245. X          printf("Data:");
  246. X          for (i=0; i<PACKET_SIZE; i++) {
  247. X               if (i && !(i % 16)) printf("\n     ");
  248. X               printf(" %02x",in[i]);
  249. X          }
  250. X          printf("\n");
  251. X#endif
  252. X          for (chk=0,i=1; i<PACKET_SIZE; i++)
  253. X               chk=(chk+in[i]) % 0xFF;
  254. X#ifdef DEBUG
  255. X          if (chk!=msg->chksum)
  256. X               printf("Bad checksum! %2x should be %2x\n",msg->chksum,chk);
  257. X#endif
  258. X     } while (chk!=msg->chksum);
  259. X     msg->load1=ntohs(msg->load1);
  260. X     msg->load2=ntohs(msg->load2);
  261. X     msg->load3=ntohs(msg->load3);
  262. X     msg->users=ntohs(msg->users);
  263. X     msg->console=ntohs(msg->console);
  264. X     msg->tmp=ntohl(msg->tmp);
  265. X     msg->uid=ntohs(msg->uid);
  266. X     return(RV_nOK);
  267. X}
  268. X
  269. X
  270. X#ifdef __STDC__
  271. Xint netSetup(void)
  272. X#else
  273. Xint netSetup()
  274. X#endif
  275. X{
  276. X     struct servent *servptr;
  277. X     int portno;
  278. X
  279. X     servptr=getservbyname(NETUSE_SERVICE,NULL);
  280. X     if (servptr==NULL) portno=NETUSE_PORT;
  281. X     else portno=servptr->s_port;
  282. X     sock=socket(AF_INET,SOCK_DGRAM,0);
  283. X     if (sock<0) {
  284. X          perror("Acquiring a socket");
  285. X          return(1);
  286. X     }
  287. X     myname.sin_family=AF_INET;
  288. X     myname.sin_addr.s_addr=INADDR_ANY;
  289. X     myname.sin_port=portno;
  290. X     if (bind(sock,&myname,sizeof(myname))) {
  291. X          perror("Binding socket");
  292. X          return(1);
  293. X     }
  294. X     return(0);
  295. X}
  296. X
  297. X
  298. X#ifdef __STDC__
  299. Xvoid netShutdown(void)
  300. X#else
  301. Xvoid netShutdown()
  302. X#endif
  303. X{
  304. X     close(sock);
  305. X}
  306. X
  307. X
  308. X#ifdef __STDC__
  309. Xint handleReport(USEREC *msg,struct sockaddr_in *src)
  310. X#else
  311. Xint handleReport(msg,src)
  312. XUSEREC *msg;
  313. Xstruct sockaddr_in *src;
  314. X#endif
  315. X{
  316. X     char hostname[255];
  317. X     VARENTRY *ventry;
  318. X
  319. X     ventry=varAllocate();
  320. X     bcopy(&(src->sin_addr.s_addr),&(ventry->ip_addr),sizeof(ventry->ip_addr));
  321. X     if (netGetHostname(ventry->ip_addr,hostname)==NULL) return(-1);
  322. X     ventry->name=(char *)malloc(strlen(hostname)+1);
  323. X     strcpy(ventry->name,hostname);
  324. X     ventry->l1=1.0*msg->load1/100;
  325. X     ventry->l2=1.0*msg->load2/100;
  326. X     ventry->l3=1.0*msg->load3/100;
  327. X     ventry->users=msg->users;
  328. X     ventry->console=msg->console;
  329. X     ventry->tmp=msg->tmp;
  330. X     ventry->machine=msg->machine;
  331. X     ventry->model=msg->model;
  332. X     varSet(ventry);
  333. X     varFree(ventry);
  334. X#ifdef ACKNOWLEDGE
  335. X     msg.opcode=OP_NOP;
  336. X     msg.ack=RV_ACK;
  337. X     packetSend(msg,src);
  338. X#endif
  339. X     return(0);
  340. X}
  341. X
  342. X
  343. X/*****************************************************************************
  344. X void logit(msg)
  345. X
  346. X This function logs a message in the (previously opened) logfile.  Note that
  347. X fflush() is used to ensure that the message gets logged to disk.
  348. X*****************************************************************************/
  349. X
  350. X#ifdef __STDC__
  351. Xvoid logit(char *msg)
  352. X#else
  353. Xvoid logit(msg)
  354. Xchar *msg;
  355. X#endif
  356. X{
  357. X     char atime[64];
  358. X     struct timeval tv;
  359. X     struct timezone tz;
  360. X     int retries;
  361. X     FILE *logf;
  362. X
  363. X     gettimeofday(&tv,&tz);
  364. X     strcpy(atime,asctime(localtime(&(tv.tv_sec))));
  365. X     atime[strlen(atime)-1]='\0';
  366. X     for (retries=0; (retries<5) && ((logf=fopen(NETUSELOG,"a"))==NULL); ++retries)
  367. X          sleep(5);
  368. X     if (retries==5) {
  369. X          fprintf(stderr,"Unable to open log file %s for update.\n",NETUSELOG);
  370. X          return;
  371. X     }
  372. X     fprintf(logf,"%s -- %s\n",atime,msg);
  373. X     fclose(logf);
  374. X     chmod(NETUSELOG,0644);
  375. X}
  376. X
  377. X
  378. X#ifdef __STDC__
  379. Xvoid logQuery(VARENTRY *template,u_short uid,struct sockaddr_in *src)
  380. X#else
  381. Xvoid logQuery(template,uid,src)
  382. XVARENTRY *template;
  383. Xu_short uid;
  384. Xstruct sockaddr_in *src;
  385. X#endif
  386. X{
  387. X     char it[132],source[80],mtype[20],modtype[16],id[30];
  388. X     struct passwd *pwptr;
  389. X
  390. X     netGetHostname(src->sin_addr.s_addr,source);
  391. X     netGetMachType(template->machine,mtype);
  392. X     netGetModelType(template->model,modtype);
  393. X     pwptr=getpwuid(uid);
  394. X     if (pwptr!=NULL) strcpy(id,pwptr->pw_name);
  395. X     else sprintf(id,"%hu",uid);
  396. X     sprintf(it,"getmach: (%s,%s) <- %s %0.2f %0.2f %0.2f %hd %s %ld %s %s",
  397. X             id,source,(strlen(template->name) ? template->name : "(none)"),
  398. X             template->l1,template->l2,template->l3,template->users,
  399. X             (template->console ? "YES" : "NO"),template->tmp,mtype,modtype);
  400. X     logit(it);
  401. X}
  402. X
  403. X
  404. X#ifdef __STDC__
  405. Xvoid logList(u_char opcode,u_char machine,u_char model,u_short uid,struct sockaddr_in *src)
  406. X#else
  407. Xvoid logList(opcode,machine,model,uid,src)
  408. Xu_char opcode,machine,model;
  409. Xu_short uid;
  410. Xstruct sockaddr_in *src;
  411. X#endif
  412. X{
  413. X     char it[132],source[80],type[32],mtype[20],modtype[16],id[30];
  414. X     struct passwd *pwptr;
  415. X
  416. X     switch (opcode) {
  417. X          case OP_GETLIST:
  418. X          case OP_GETMLIST:
  419. X               strcpy(type,"ALL");
  420. X               break;
  421. X          case OP_DISPLIST:
  422. X          case OP_DISPMLIST:
  423. X               strcpy(type,"TEN");
  424. X               break;
  425. X          case OP_GETDOWN:
  426. X          case OP_GETMDOWN:
  427. X               strcpy(type,"DOWN");
  428. X               break;
  429. X          default:
  430. X               strcpy(type,"ERROR!");
  431. X               break;
  432. X     }
  433. X     netGetHostname(src->sin_addr.s_addr,source);
  434. X     netGetMachType(machine,mtype);
  435. X     netGetModelType(model,modtype);
  436. X     pwptr=getpwuid(uid);
  437. X     if (pwptr!=NULL) strcpy(id,pwptr->pw_name);
  438. X     else sprintf(id,"%hu",uid);
  439. X     sprintf(it,"hostinfo: (%s,%s) %s %s %s",id,source,type,mtype,modtype);
  440. X     logit(it);
  441. X}
  442. X
  443. X
  444. X#ifdef __STDC__
  445. Xint handleQuery(USEREC *msg,struct sockaddr_in *src)
  446. X#else
  447. Xint handleQuery(msg,src)
  448. XUSEREC *msg;
  449. Xstruct sockaddr_in *src;
  450. X#endif
  451. X{
  452. X     VARENTRY *ventry,*vptr;
  453. X
  454. X     ventry=varAllocate();
  455. X     ventry->l1=1.0*msg->load1/100;
  456. X     ventry->l2=1.0*msg->load2/100;
  457. X     ventry->l3=1.0*msg->load3/100;
  458. X     ventry->users=msg->users;
  459. X     ventry->console=msg->console;
  460. X     ventry->tmp=msg->tmp;
  461. X     ventry->machine=msg->machine;
  462. X     ventry->model=msg->model;
  463. X     vptr=varFindMatch(ventry);
  464. X     if (vptr==NULL) {
  465. X          ventry->name=(char *)malloc(1);
  466. X          ventry->name[0]='\0';
  467. X#ifdef LOGREQUESTS
  468. X          logQuery(ventry,msg->uid,src);
  469. X#endif
  470. X          msg->retcode=RV_NOMATCH;
  471. X          packetSend(msg,src);
  472. X     }
  473. X     else {
  474. X          ventry->name=(char *)malloc(strlen(vptr->name)+1);
  475. X          strcpy(ventry->name,vptr->name);
  476. X#ifdef LOGREQUESTS
  477. X          logQuery(ventry,msg->uid,src);
  478. X#endif
  479. X          msg->ipaddr=netGetAddress(ventry->name);
  480. X          msg->retcode=RV_OK;
  481. X          packetSend(msg,src);
  482. X     }
  483. X     varFree(ventry);
  484. X     return(0);
  485. X}
  486. X
  487. X
  488. X#ifdef __STDC__
  489. Xint handleList(USEREC *msg,struct sockaddr_in *src)
  490. X#else
  491. Xint handleList(msg,src)
  492. XUSEREC *msg;
  493. Xstruct sockaddr_in *src;
  494. X#endif
  495. X{
  496. X     int tcpsock;
  497. X     FILE *outf;
  498. X
  499. X     tcpsock=socket(AF_INET,SOCK_STREAM,0);
  500. X     if (tcpsock<0) {
  501. X          perror("Acquiring TCP socket");
  502. X          return(-1);
  503. X     }
  504. X     src->sin_port=htons(msg->portno);
  505. X#ifdef DEBUG
  506. X     printf("About to connect()...\n");
  507. X#endif
  508. X     if (connect(tcpsock,src,sizeof(struct sockaddr_in))<0) {
  509. X          perror("Connecting to client's TCP port");
  510. X          return(-1);
  511. X     }
  512. X#ifdef DEBUG
  513. X     printf("Connection established...\n");
  514. X#endif
  515. X     if ((outf=fdopen(tcpsock,"w"))==NULL) {
  516. X          perror("fdopen");
  517. X          return(-1);
  518. X     }
  519. X#ifdef DEBUG
  520. X     printf("fdopen() established...\n");
  521. X#endif
  522. X     switch (msg->opcode) {
  523. X          case OP_GETLIST:
  524. X          case OP_GETDOWN:
  525. X          case OP_DISPLIST:
  526. X               treePrintList(outf,msg->machine,msg->model,msg->opcode);
  527. X               break;
  528. X          case OP_GETMLIST:
  529. X          case OP_GETMDOWN:
  530. X          case OP_DISPMLIST:
  531. X               treePrintListWithModels(outf,msg->machine,msg->model,msg->opcode);
  532. X               break;
  533. X          default:
  534. X#ifdef DEBUG
  535. X               printf("Don't know what type of list to print!\n");
  536. X#endif
  537. X               treePrintList(outf,msg->machine,msg->model,msg->opcode);
  538. X               break;
  539. X     }
  540. X#ifdef DEBUG
  541. X     printf("After treePrintList()...\n");
  542. X#endif
  543. X     fflush(outf);
  544. X     fclose(outf);
  545. X     close(tcpsock);
  546. X#ifdef LOGREQUESTS
  547. X     logList(msg->opcode,msg->machine,msg->model,msg->uid,src);
  548. X#endif
  549. X     return(0);
  550. X}
  551. X
  552. X
  553. X#ifdef __STDC__
  554. Xint handleHostAdd(USEREC *msg,struct sockaddr_in *src)
  555. X#else
  556. Xint handleHostAdd(msg,src)
  557. XUSEREC *msg;
  558. Xstruct sockaddr_in *src;
  559. X#endif
  560. X{
  561. X     char hostname[255],temp[132];
  562. X     VARENTRY *ventry;
  563. X
  564. X     ventry=varAllocate();
  565. X     ventry->ip_addr=msg->ipaddr;
  566. X     if (netGetHostname(ventry->ip_addr,hostname)==NULL) return(-1);
  567. X     ventry->name=(char *)malloc(strlen(hostname)+1);
  568. X     strcpy(ventry->name,hostname);
  569. X     ventry->machine=msg->machine;
  570. X     ventry->model=msg->model;
  571. X     varAdd(ventry);
  572. X     varFree(ventry);
  573. X     sprintf(temp,"Added host %s of type (%d,%d).",hostname,msg->machine,msg->model);
  574. X     logit(temp);
  575. X     msg->retcode=RV_OK;
  576. X     msg->ack=RV_ACK;
  577. X     packetSend(msg,src);
  578. X     return(0);
  579. X}
  580. X
  581. X
  582. X#ifdef __STDC__
  583. Xint handleHostDelete(USEREC *msg,struct sockaddr_in *src)
  584. X#else
  585. Xint handleHostDelete(msg,src)
  586. XUSEREC *msg;
  587. Xstruct sockaddr_in *src;
  588. X#endif
  589. X{
  590. X     char hostname[255],temp[255];
  591. X     VARENTRY *ventry;
  592. X
  593. X     ventry=varAllocate();
  594. X     ventry->ip_addr=msg->ipaddr;
  595. X     if (netGetHostname(ventry->ip_addr,hostname)==NULL) {
  596. X          msg->retcode=RV_NOMATCH;
  597. X          packetSend(msg,src);
  598. X          return(0);
  599. X     }
  600. X     ventry->name=(char *)malloc(strlen(hostname)+1);
  601. X     strcpy(ventry->name,hostname);
  602. X     varDelete(ventry);
  603. X     varFree(ventry);
  604. X     msg->retcode=RV_OK;
  605. X     msg->ack=RV_ACK;
  606. X     packetSend(msg,src);
  607. X     sprintf(temp,"Deleted host %s",hostname);
  608. X     logit(temp);
  609. X     return(0);
  610. X}
  611. X
  612. X
  613. X#ifdef __STDC__
  614. Xint handleStateSave(USEREC *msg,struct sockaddr_in *src)
  615. X#else
  616. Xint handleStateSave(msg,src)
  617. XUSEREC *msg;
  618. Xstruct sockaddr_in *src;
  619. X#endif
  620. X{
  621. X     msg->retcode=varSaveState();
  622. X     msg->ack=RV_ACK;
  623. X     packetSend(msg,src);
  624. X     return(0);
  625. X}
  626. X
  627. X
  628. X#ifdef __STDC__
  629. Xint handleHostLoad(USEREC *msg,struct sockaddr_in *src)
  630. X#else
  631. Xint handleHostLoad(msg,src)
  632. XUSEREC *msg;
  633. Xstruct sockaddr_in *src;
  634. X#endif
  635. X{
  636. X     msg->retcode=varLoadHosts();
  637. X     msg->ack=RV_ACK;
  638. X     packetSend(msg,src);
  639. X     return(0);
  640. X}
  641. X
  642. X
  643. X#ifdef __STDC__
  644. Xvoid WakeTheDead(void)
  645. X#else
  646. Xvoid WakeTheDead()
  647. X#endif
  648. X{
  649. X     VARENTRY *vptr,*vprev;
  650. X     int i,socket;
  651. X     struct servent *servptr;
  652. X     struct sockaddr_in dest;
  653. X     u_long ip;
  654. X     char buf[128];
  655. X     long lastrep;
  656. X
  657. X#ifdef DEBUG
  658. X     logit("Checking for dead daemons.  (Can daemons die?)");
  659. X#endif
  660. X     servptr=getservbyname(NETUSED_SERVICE,NULL);
  661. X     if (servptr==NULL) dest.sin_port=NETUSED_PORT;
  662. X     else dest.sin_port=servptr->s_port;
  663. X     dest.sin_family=AF_INET;
  664. X     for (i=0; i<VAR_ENTRIES; i++) {
  665. X          vprev=NULL;
  666. X          for (vptr=variables[i]; vptr!=NULL; vptr=vptr->next) {
  667. X               if (!vptr->logtime) lastrep=netuseStartTime;
  668. X               else lastrep=vptr->logtime;
  669. X               if ((time(NULL)-lastrep)>=GIVEUPTIME*60) {
  670. X                    sprintf(buf,"Retiring host %s.",vptr->name);
  671. X                    logit(buf);
  672. X                    if (vprev==NULL) variables[i]=vptr->next;
  673. X                    else vprev->next=vptr->next;
  674. X                    varFree(vptr);
  675. X                    sprintf(buf,"Host %s has been retired.",vptr->name);
  676. X                    logit(buf);
  677. X                    if (vprev==NULL) {
  678. X                         if ((vptr=variables[i])==NULL) break;
  679. X                    }
  680. X                    else vptr=vprev;
  681. X                    continue;      /* vprev is already correct for next loop */
  682. X               }
  683. X               if ((time(NULL)-lastrep)>=DOWNTIME*60) {
  684. X                    if (ip=netGetAddress(vptr->name)) {
  685. X                         dest.sin_addr.s_addr=ip;
  686. X#ifdef LOGWAKEUPS
  687. X                         sprintf(buf,"Yo!  (Waking up %s)...",vptr->name);
  688. X                         logit(buf);
  689. X#endif
  690. X                         if (sendto(sock,"Wakeup!",9,0,&dest,sizeof(dest))==(-1)) {
  691. X                              sprintf(buf,"Error %d from sendto() in WakeTheDead().\n",
  692. X                                          errno);
  693. X                              logit(buf);
  694. X                         }
  695. X                    }
  696. X               }
  697. X               vprev=vptr;
  698. X          }
  699. X     }
  700. X}
  701. X
  702. X
  703. X#ifdef __STDC__
  704. Xint netGetRequest(USEREC *msg,struct sockaddr_in *src)
  705. X#else
  706. Xint netGetRequest(msg,src)
  707. XUSEREC *msg;
  708. Xstruct sockaddr_in *src;
  709. X#endif
  710. X{
  711. X     return(packetReceive(msg,src));
  712. X}
  713. X
  714. X
  715. X#ifdef __STDC__
  716. Xint netHandleRequest(USEREC *msg,struct sockaddr_in *src)
  717. X#else
  718. Xint netHandleRequest(msg,src)
  719. XUSEREC *msg;
  720. Xstruct sockaddr_in *src;
  721. X#endif
  722. X{
  723. X     switch (msg->opcode) {
  724. X          case OP_STATUS:
  725. X               handleReport(msg,src);
  726. X               break;
  727. X          case OP_QUERY:
  728. X               handleQuery(msg,src);
  729. X               break;
  730. X          case OP_GETLIST:
  731. X          case OP_GETDOWN:
  732. X          case OP_DISPLIST:
  733. X          case OP_GETMLIST:
  734. X          case OP_GETMDOWN:
  735. X          case OP_DISPMLIST:
  736. X               handleList(msg,src);
  737. X               break;
  738. X          case OP_ADDHOST:
  739. X               handleHostAdd(msg,src);
  740. X               break;
  741. X          case OP_DELHOST:
  742. X               handleHostDelete(msg,src);
  743. X               break;
  744. X          case OP_SAVESTATE:
  745. X               handleStateSave(msg,src);
  746. X               break;
  747. X          case OP_LOADHOSTS:
  748. X               handleHostLoad(msg,src);
  749. X               break;
  750. X/*        case OP_TEXTSTATUS:
  751. X               handleTextReport(msg,src,0);
  752. X               break;
  753. X          case OP_TEXTSTATUS2:
  754. X               handleTextReport(msg,src,1);
  755. X               break; */
  756. X          default:
  757. X               printf("Unknown opcode received...\n");
  758. X               break;
  759. X     }
  760. X     if ((time(0)-lastCheck)>DOWNTIME*60) {
  761. X          WakeTheDead();
  762. X          lastCheck=time(0);
  763. X     }
  764. X     if ((time(0)-lastSave)>DOWNTIME*60) {
  765. X          varSaveState();
  766. X          lastSave=time(0);
  767. X     }
  768. X     return(0);
  769. X}
  770. X
  771. X
  772. X#ifdef __STDC__
  773. Xmain(int argc,char *argv[])
  774. X#else
  775. Xmain(argc,argv)
  776. Xint argc;
  777. Xchar *argv[];
  778. X#endif
  779. X{
  780. X     USEREC msg;
  781. X     struct sockaddr_in src;
  782. X
  783. X     if (fork()) exit(0);
  784. X     varInit();
  785. X     netuseStartTime=lastCheck=lastSave=time(0);
  786. X     while (netSetup()) 
  787. X          sleep(5);
  788. X     for ( ; ; ) {
  789. X          netGetRequest(&msg,&src);
  790. X#ifdef DEBUG
  791. X          printf("About to call netHandleRequest()...\n");
  792. X#endif
  793. X          netHandleRequest(&msg,&src);
  794. X#ifdef DEBUG
  795. X          printf("Back from netHandleRequest().\n");
  796. X#endif
  797. X     }
  798. X     netShutdown();
  799. X     varFreeTable();
  800. X}
  801. END_OF_FILE
  802.   if test 20734 -ne `wc -c <'netuse/daemons/netuse.c'`; then
  803.     echo shar: \"'netuse/daemons/netuse.c'\" unpacked with wrong size!
  804.   fi
  805.   # end of 'netuse/daemons/netuse.c'
  806. fi
  807. if test -f 'netuse/daemons/netused.c' -a "${1}" != "-c" ; then 
  808.   echo shar: Will not clobber existing file \"'netuse/daemons/netused.c'\"
  809. else
  810.   echo shar: Extracting \"'netuse/daemons/netused.c'\" \(13050 characters\)
  811.   sed "s/^X//" >'netuse/daemons/netused.c' <<'END_OF_FILE'
  812. X/******************************************************************************
  813. X NETUSED.C - Network Host Use Monitor Daemon
  814. X
  815. X This program runs on a host machine on a network and periodically reports
  816. X information about the machine to the NETUSE server.  Currently, the
  817. X information sent includes the load averages, number of active users, use of
  818. X the console, machine type, and the kilobytes of free space on the /tmp
  819. X filesystem.
  820. X
  821. X Lee Liming and Michael Neil, The Computer Aided Engineering Network
  822. X The University of Michigan
  823. X
  824. X Copyright (C) 1990, 1991, 1992 by the Regents of the University of Michigan.
  825. X
  826. X User agrees to reproduce said copyright notice on all copies of the software
  827. X made by the recipient.  
  828. X
  829. X All Rights Reserved. Permission is hereby granted for the recipient to make
  830. X copies and use this software for its own internal purposes only. Recipient of
  831. X this software may re-distribute this software outside of their own
  832. X institution. Permission to market this software commercially, to include this
  833. X product as part of a commercial product, or to make a derivative work for
  834. X commercial purposes, is explicitly prohibited.  All other uses are also
  835. X prohibited unless authorized in writing by the Regents of the University of
  836. X Michigan.
  837. X
  838. X This software is offered without warranty. The Regents of the University of
  839. X Michigan disclaim all warranties, express or implied, including but not
  840. X limited to the implied warranties of merchantability and fitness for any
  841. X particular purpose. In no event shall the Regents of the University of
  842. X Michigan be liable for loss or damage of any kind, including but not limited
  843. X to incidental, indirect, consequential, or special damages. 
  844. X******************************************************************************/
  845. X
  846. X#include <stdio.h>
  847. X#include <sys/types.h>
  848. X#include <fcntl.h>
  849. X#include <sys/socket.h>
  850. X#include <netinet/in.h>
  851. X#include <netdb.h>
  852. X#include <fcntl.h>
  853. X#include <signal.h>
  854. X#include <setjmp.h>
  855. X#include <sys/time.h>
  856. X#include <sys/errno.h>
  857. X#ifdef hpux
  858. X#include <unistd.h>
  859. X#endif
  860. X#if (defined(_AIX) || defined(apollo))
  861. X#include <sys/ioctl.h>
  862. X#else
  863. X#include <sys/termios.h>
  864. X#endif
  865. X#ifdef _AIX
  866. X#include <sys/select.h>
  867. X#endif
  868. X#include "../lib/protocol.h"
  869. X#include "../lib/netuse.h"
  870. X#include "../lib/config.h"
  871. X#include "caenlab.h"
  872. X
  873. X
  874. X/* #define DEBUG */
  875. X
  876. X
  877. Xextern errno;
  878. X
  879. Xint sock;
  880. Xstruct sockaddr_in servername,clientname;
  881. Xjmp_buf jumpTimeout;
  882. Xu_char modelMine=0;
  883. X
  884. Xint  netSetup();
  885. Xvoid netShutdown();
  886. X
  887. X
  888. X/*****************************************************************************
  889. X void logit(msg)
  890. X
  891. X This function logs a message in the logfile.
  892. X*****************************************************************************/
  893. X
  894. X#ifdef __STDC__
  895. Xvoid logit(char *msg)
  896. X#else
  897. Xvoid logit(msg)
  898. Xchar *msg;
  899. X#endif
  900. X{
  901. X     char atime[64],buf[132];
  902. X     struct timeval tv;
  903. X     struct timezone tz;
  904. X     int retries;
  905. X     FILE *logf;
  906. X
  907. X     gettimeofday(&tv,&tz);
  908. X     strcpy(atime,asctime(localtime(&(tv.tv_sec))));
  909. X     atime[strlen(atime)-1]='\0';
  910. X     for (retries=0; (retries<5) && ((logf=fopen(NETUSEDLOG,"a"))==NULL); ++retries)
  911. X          sleep(5);
  912. X     if (retries==5) {
  913. X          fprintf(stderr,"Unable to open log file %s for update.\n",NETUSEDLOG);
  914. X          return;
  915. X     }
  916. X     fprintf(logf,"%s -- %s\n",atime,msg);
  917. X     fclose(logf);
  918. X     chmod(NETUSEDLOG,0644);
  919. X}
  920. X
  921. X
  922. X#ifdef __STDC__
  923. Xint packetSend(USEREC *msg)
  924. X#else
  925. Xint packetSend(msg)
  926. XUSEREC *msg;
  927. X#endif
  928. X{
  929. X     u_char chk;
  930. X     int rv,count,i;
  931. X     PACKET out;
  932. X     char buf[132];
  933. X
  934. X     if (netSetup()) return(RV_nBADSEND);
  935. X     msg->load1=htons(msg->load1);
  936. X     msg->load2=htons(msg->load2);
  937. X     msg->load3=htons(msg->load3);
  938. X     msg->users=htons(msg->users);
  939. X     msg->console=htons(msg->console);
  940. X     msg->tmp=htonl(msg->tmp);
  941. X     msg->uid=htons(msg->uid);
  942. X     bcopy(msg,out,sizeof(PACKET));
  943. X     for (chk=0,i=1; i<PACKET_SIZE; i++)
  944. X          chk=(chk+out[i]) % 0xFF;
  945. X     out[0]=chk;
  946. X#ifdef DEBUG
  947. X     logit("Client sending:");
  948. X     sprintf(buf,"Opcode=%02x Retcode=%02x Ack=%02x Load1=%04x Load2=%04x Load3=%04x Users=%04x Console=%04x /tmp=%08x Mach=%02x Model=%02x Chksum=%02x",
  949. X            msg->opcode,msg->retcode,msg->ack,ntohs(msg->load1),
  950. X            ntohs(msg->load2),ntohs(msg->load3),ntohs(msg->users),
  951. X            ntohs(msg->console),ntohl(msg->tmp),msg->machine,msg->model,out[0]);
  952. X     logit(buf);
  953. X#endif
  954. X     count=0;
  955. X     do {
  956. X          rv=sendto(sock,out,PACKET_SIZE,0,
  957. X                    &servername,sizeof(struct sockaddr));
  958. X          if (rv==(-1)) {
  959. X               logit("Problem with sendto().");
  960. X               if (++count>SEND_RETRIES) {
  961. X                    netShutdown();
  962. X                    return(RV_nBADSEND);
  963. X               }
  964. X          }
  965. X     } while (rv!=PACKET_SIZE);
  966. X     netShutdown();
  967. X     return(RV_nOK);
  968. X}
  969. X
  970. X
  971. X#ifdef __STDC__
  972. Xint AlarmHandler(int sig)
  973. X#else
  974. Xint AlarmHandler(sig)
  975. Xint sig;
  976. X#endif
  977. X{
  978. X     longjmp(jumpTimeout,1);
  979. X     return(0);
  980. X}
  981. X
  982. X
  983. X#ifdef __STDC__
  984. Xint packetReceive(USEREC *msg)
  985. X#else
  986. Xint packetReceive(msg)
  987. XUSEREC *msg;
  988. X#endif
  989. X{
  990. X     u_char chk;
  991. X     int i;
  992. X     PACKET in;
  993. X     char buf[132];
  994. X
  995. X     if (netSetup()) return(RV_nBADRECV);
  996. X     do {
  997. X          signal(SIGALRM,AlarmHandler);
  998. X          if (setjmp(jumpTimeout)!=0) return(RV_nTIMEOUT);
  999. X          alarm(TIMEOUT);
  1000. X          i=sizeof(struct sockaddr);
  1001. X          if (recvfrom(sock,in,PACKET_SIZE,0,
  1002. X                       &servername,&i)==(-1)) {
  1003. X               logit("Problem with recvfrom().");
  1004. X               netShutdown();
  1005. X               return(RV_nBADRECV);
  1006. X          }
  1007. X          alarm(0);
  1008. X          signal(SIGALRM,SIG_DFL);
  1009. X          bcopy(in,msg,sizeof(PACKET));
  1010. X#ifdef DEBUG
  1011. X          logit("Client received:");
  1012. X          sprintf(buf,"Opcode=%02x Retcode=%02x Ack=%02x Load1=%04x Load2=%04x Load3=%04x Users=%04x Console=%04x /tmp=%08x Mach=%02x Model=%02x Chksum=%02x",
  1013. X                 msg->opcode,msg->retcode,msg->ack,ntohs(msg->load1),
  1014. X                 ntohs(msg->load2),ntohs(msg->load3),ntohs(msg->users),
  1015. X                 ntohs(msg->console),ntohl(msg->tmp),msg->machine,msg->model,in[0]);
  1016. X          logit(buf);
  1017. X#endif
  1018. X          for (chk=0,i=1; i<PACKET_SIZE; i++)
  1019. X               chk=(chk+in[i]) % 0xFF;
  1020. X     } while (chk!=in[0]);
  1021. X     msg->load1=ntohs(msg->load1);
  1022. X     msg->load2=ntohs(msg->load2);
  1023. X     msg->load3=ntohs(msg->load3);
  1024. X     msg->users=ntohs(msg->users);
  1025. X     msg->console=ntohs(msg->console);
  1026. X     msg->tmp=ntohl(msg->tmp);
  1027. X     msg->uid=ntohs(msg->uid);
  1028. X     netShutdown();
  1029. X     return(RV_nOK);
  1030. X}
  1031. X
  1032. X
  1033. X#ifdef __STDC__
  1034. Xint netSetup(void)
  1035. X#else
  1036. Xint netSetup()
  1037. X#endif
  1038. X{
  1039. X     struct hostent *hp;
  1040. X     struct servent *servptr;
  1041. X     int portno;
  1042. X
  1043. X     sock=socket(AF_INET,SOCK_DGRAM,0);
  1044. X     if (sock<0) {
  1045. X          logit("Problem acquiring main socket");
  1046. X          return(1);
  1047. X     }
  1048. X     clientname.sin_family=AF_INET;
  1049. X     clientname.sin_addr.s_addr=INADDR_ANY;
  1050. X     clientname.sin_port=0;
  1051. X     if (bind(sock,&clientname,sizeof(clientname))) {
  1052. X          logit("Unable to bind main socket");
  1053. X          close(sock);
  1054. X          return(1);
  1055. X     }
  1056. X     servptr=getservbyname(NETUSE_SERVICE,NULL);
  1057. X     if (servptr==NULL) htons(portno=NETUSE_PORT);
  1058. X     else portno=htons(servptr->s_port);
  1059. X     hp=gethostbyname(NETUSE_SERVER);
  1060. X     if (hp==NULL) {
  1061. X          logit("Unable to get server address");
  1062. X          close(sock);
  1063. X          return(1);
  1064. X     }
  1065. X     bcopy(hp->h_addr,&servername.sin_addr,hp->h_length);
  1066. X     servername.sin_family=AF_INET;
  1067. X     servername.sin_port=htons(portno);
  1068. X     return(0);
  1069. X}
  1070. X
  1071. X
  1072. X#ifdef __STDC__
  1073. Xvoid netShutdown(void)
  1074. X#else
  1075. Xvoid netShutdown()
  1076. X#endif
  1077. X{
  1078. X     close(sock);
  1079. X}
  1080. X
  1081. X
  1082. X#ifdef __STDC__
  1083. Xint report(float load1,float load2,float load3,int users,int console,long tmp)
  1084. X#else
  1085. Xint report(load1,load2,load3,users,console,tmp)
  1086. Xfloat load1,load2,load3;
  1087. Xint users,console;
  1088. Xlong tmp;
  1089. X#endif
  1090. X{
  1091. X     USEREC msg;
  1092. X
  1093. X     msg.opcode=OP_STATUS;
  1094. X     msg.load1=(u_short)(load1*100);
  1095. X     msg.load2=(u_short)(load2*100);
  1096. X     msg.load3=(u_short)(load3*100);
  1097. X     msg.users=(u_short)users;
  1098. X     msg.console=(u_short)console;
  1099. X     msg.tmp=(u_long)tmp;
  1100. X     msg.machine=(u_char)MACHINETYPE;
  1101. X     msg.model=(u_char)modelMine;
  1102. X     msg.retcode=RV_OK;
  1103. X     packetSend(&msg);
  1104. X#ifdef ACKNOWLEDGE
  1105. X     if (err=packetReceive(&msg)) {
  1106. X          switch (err) {
  1107. X               case RV_nTIMEOUT:
  1108. X                    return(RV_TIMEOUT);
  1109. X          }
  1110. X     }
  1111. X#endif
  1112. X     return(0);
  1113. X}
  1114. X
  1115. X
  1116. X#ifdef __STDC__
  1117. Xvoid inputClean(void)
  1118. X#else
  1119. Xvoid inputClean()
  1120. X#endif
  1121. X{
  1122. X     fd_set read_template;                    /* Descriptors to be read from */
  1123. X     struct timeval tvTimeout;
  1124. X     char inbuf[1024],buf[132];
  1125. X     int more,rv,size;
  1126. X     struct hostent *hp;
  1127. X     struct servent *servptr;
  1128. X     int i;
  1129. X
  1130. X     i=0;
  1131. X     do {
  1132. X#ifdef DEBUG
  1133. X          sprintf(buf,"Checking for waiting input...",rv);
  1134. X          logit(buf);
  1135. X#endif
  1136. X          FD_ZERO(&read_template);
  1137. X          FD_SET(0,&read_template);
  1138. X          tvTimeout.tv_sec=0;
  1139. X          tvTimeout.tv_usec=0;
  1140. X          rv=select(FD_SETSIZE,&read_template,(fd_set *)0,(fd_set *)0,
  1141. X                    &tvTimeout);
  1142. X          if (rv<0) {
  1143. X#ifdef DEBUG
  1144. X                sprintf(buf,"select() returned error %d.",rv);
  1145. X                logit(buf);
  1146. X#endif
  1147. X                return;
  1148. X          }
  1149. X          if (more=FD_ISSET(0,&read_template)) {
  1150. X#ifdef DEBUG
  1151. X               sprintf(buf,"Found waiting input.  Reading it.",rv);
  1152. X               logit(buf);
  1153. X#endif
  1154. X               size=0;
  1155. X               if ((rv=recvfrom(0,inbuf,sizeof(inbuf),0,NULL,&size))<0) {
  1156. X                    if (errno==ENOTSOCK) {
  1157. X                         logit("Input is not a socket -- ignoring.");
  1158. X                         more=0;
  1159. X                    }
  1160. X                    if (errno==EBADF) {
  1161. X                         logit("Bad descriptor on input -- ignoring.");
  1162. X                         more=0;
  1163. X                    }
  1164. X                    if (i>1000) {
  1165. X                         logit("Too many errors.  Ignoring input.");
  1166. X                         more=0;
  1167. X                    }
  1168. X                    sprintf(buf,"recvfrom() returned error %d.",errno);
  1169. X                    logit(buf);
  1170. X                    ++i;
  1171. X                    if (i>=100) {
  1172. X                         logit("Too many errors.  Ignoring input.");
  1173. X                         more=0;
  1174. X                    }
  1175. X               }
  1176. X#ifdef DEBUG
  1177. X               else {
  1178. X                    sprintf(buf,"Read %d bytes of input.\n",rv);
  1179. X                    logit(buf);
  1180. X               }
  1181. X#endif
  1182. X          }
  1183. X          else {
  1184. X#ifdef DEBUG
  1185. X               sprintf(buf,"No available input.",rv);
  1186. X               logit(buf);
  1187. X#endif
  1188. X          }
  1189. X     } while (more);
  1190. X/*
  1191. X#ifdef DEBUG
  1192. X     logit("Before close().");
  1193. X#endif
  1194. X     close(0);
  1195. X#ifdef DEBUG
  1196. X     logit("After close().");
  1197. X#endif
  1198. X*/
  1199. X}
  1200. X
  1201. X
  1202. X#ifdef __STDC__
  1203. Xvoid StopEverything(void)
  1204. X#else
  1205. Xvoid StopEverything()
  1206. X#endif
  1207. X{
  1208. X     char hostname[132],buf[132];
  1209. X     int rv;
  1210. X
  1211. X     gethostname(hostname,sizeof(hostname));
  1212. X     if (rv=netuseDelName(hostname)) {
  1213. X          sprintf(buf,"netuseDelName() returned %d.",rv);
  1214. X          logit(buf);
  1215. X     }
  1216. X     logit("Not gonna run.");
  1217. X     exit(0);
  1218. X}
  1219. X
  1220. X
  1221. X#ifdef __STDC__
  1222. Xmain(int argc,char *argv[])
  1223. X#else
  1224. Xmain(argc,argv)
  1225. Xint argc;
  1226. Xchar *argv[];
  1227. X#endif
  1228. X{
  1229. X     int time,period,mode,i,awakenings;
  1230. X     double GetLoadPoint();
  1231. X     long getdisk();
  1232. X     int getusers();
  1233. X     u_char modelDetect();
  1234. X     double l1,l2,l3;
  1235. X     int users,console;
  1236. X     int fd;
  1237. X     long tmp;
  1238. X     char temp[132],buf[512];
  1239. X
  1240. X     inputClean();
  1241. X#ifdef hpux
  1242. X     if (setsid()<0) logit("setsid() returned an error.");
  1243. X#else
  1244. X     if ((fd=open("/dev/tty",O_RDWR,0))!=(-1)) {   /* Detach controlling tty */
  1245. X          ioctl(fd,TIOCNOTTY,0);
  1246. X          close(fd);
  1247. X     }
  1248. X#endif
  1249. X     /* if (fork()) exit(0); */
  1250. X     mode=0;
  1251. X     time=DEFAULT_PERIOD;
  1252. X     period=REPORT_CYCLE;
  1253. X     for (i=1; argc>i; i++)
  1254. X          if ((argv[i][0]=='-') || (argv[i][0]=='/')) {
  1255. X               strcpy(temp,argv[i]+1);
  1256. X               stoupper(temp);
  1257. X               if (!strcmp(temp,"ONCE")) mode=1;
  1258. X               if (!strcmp(temp,"FORCE")) mode=2;
  1259. X               if (!strcmp(temp,"WAKEUP")) {
  1260. X                    if (argc>(++i)) time=atoi(argv[i]);
  1261. X                    else logit("Missing value for -wakeup option.");
  1262. X               }
  1263. X               if (!strcmp(temp,"REPORT")) {
  1264. X                    if (argc>(++i)) period=atoi(argv[i]);
  1265. X                    else logit("Missing value for -report option.");
  1266. X               }
  1267. X               if (!strcmp(temp,"INETD")) {
  1268. X                    while (read(0,buf,512))           /* Empty socket buffer */
  1269. X                         ;
  1270. X                    close(0); close(1);
  1271. X               }
  1272. X          }
  1273. X#ifdef USE_CAENLAB
  1274. X     if (!netusedShouldRun() && !mode) StopEverything();
  1275. X#endif
  1276. X     InitGetLoad();
  1277. X     modelMine=modelDetect();
  1278. X     awakenings=REPORT_CYCLE;
  1279. X     do {
  1280. X          GetLoadPoint(&l1,&l2,&l3);
  1281. X          getusers(&users,&console);
  1282. X          tmp=getdisk();
  1283. X          if (awakenings==REPORT_CYCLE) {
  1284. X               report((float)l1,(float)l2,(float)l3,users,console,tmp);
  1285. X               awakenings=1;
  1286. X          }
  1287. X          else ++awakenings;
  1288. X          if (mode!=1) sleep(time);
  1289. X     } while (mode!=1);
  1290. X}
  1291. END_OF_FILE
  1292.   if test 13050 -ne `wc -c <'netuse/daemons/netused.c'`; then
  1293.     echo shar: \"'netuse/daemons/netused.c'\" unpacked with wrong size!
  1294.   fi
  1295.   # end of 'netuse/daemons/netused.c'
  1296. fi
  1297. if test -f 'netuse/lib/gethost.c' -a "${1}" != "-c" ; then 
  1298.   echo shar: Will not clobber existing file \"'netuse/lib/gethost.c'\"
  1299. else
  1300.   echo shar: Extracting \"'netuse/lib/gethost.c'\" \(13002 characters\)
  1301.   sed "s/^X//" >'netuse/lib/gethost.c' <<'END_OF_FILE'
  1302. X/******************************************************************************
  1303. X GETHOST.C - Client routines for finding hosts of various types
  1304. X
  1305. X The routines in this file are all related to querying the NETUSE server to
  1306. X find hosts which match certain criteria.
  1307. X
  1308. X Lee Liming and Michael Neil, The Computer Aided Engineering Network
  1309. X The University of Michigan
  1310. X
  1311. X Copyright (C) 1990, 1991, 1992 by the Regents of the University of Michigan.
  1312. X
  1313. X User agrees to reproduce said copyright notice on all copies of the software
  1314. X made by the recipient.  
  1315. X
  1316. X All Rights Reserved. Permission is hereby granted for the recipient to make
  1317. X copies and use this software for its own internal purposes only. Recipient of
  1318. X this software may re-distribute this software outside of their own
  1319. X institution. Permission to market this software commercially, to include this
  1320. X product as part of a commercial product, or to make a derivative work for
  1321. X commercial purposes, is explicitly prohibited.  All other uses are also
  1322. X prohibited unless authorized in writing by the Regents of the University of
  1323. X Michigan.
  1324. X
  1325. X This software is offered without warranty. The Regents of the University of
  1326. X Michigan disclaim all warranties, express or implied, including but not
  1327. X limited to the implied warranties of merchantability and fitness for any
  1328. X particular purpose. In no event shall the Regents of the University of
  1329. X Michigan be liable for loss or damage of any kind, including but not limited
  1330. X to incidental, indirect, consequential, or special damages. 
  1331. X******************************************************************************/
  1332. X
  1333. X#include <stdio.h>
  1334. X#include <sys/types.h>
  1335. X#ifdef IBMTCPIP
  1336. X#include <types.h>
  1337. X#endif
  1338. X#include <sys/socket.h>
  1339. X#include <netinet/in.h>
  1340. X#include <netdb.h>
  1341. X#include "protocol.h"
  1342. X#include "network.h"
  1343. X#include "netuse.h"
  1344. X
  1345. X
  1346. Xtypedef struct _models {
  1347. X             char   name[15];
  1348. X             u_char num;
  1349. X        } MODELS;
  1350. X
  1351. XMODELS models[]={{"3100",MODEL_DS3100},{"5000/200",MODEL_DS5000200},
  1352. X                 {"5000/120",MODEL_DS5000120},{"4/?",MODEL_SUN4},
  1353. X                 {"4/65",MODEL_SUN4_65},{"4/50",MODEL_SUN4_50},
  1354. X                 {"6000/320",MODEL_RS320},{"6000/520",MODEL_RS520},
  1355. X                 {"6000/530",MODEL_RS530},{"6000/540",MODEL_RS540},
  1356. X                 {"6000/730",MODEL_RS730},{"6000/930",MODEL_RS930},
  1357. X                 {"3000",MODEL_AP3000},{"3500",MODEL_AP3500},
  1358. X                 {"4000",MODEL_AP4000},{"4500",MODEL_AP4500},
  1359. X                 {"5500",MODEL_AP5500},{"10010",MODEL_AP10010},
  1360. X                 {"10020",MODEL_AP10020},{"425E",MODEL_HP425E},
  1361. X                 {"425T",MODEL_HP425T},{"9000/720",MODEL_HP9000720},
  1362. X                 {"3/?",MODEL_SUN3},{"2500",MODEL_AP2500},
  1363. X                 {"5000/133",MODEL_DS5000133},{"9000/705",MODEL_HP9000705},
  1364. X                 {"9000/710",MODEL_HP9000710},{"9000/730",MODEL_HP9000730},
  1365. X                 {"9000/750",MODEL_HP9000750},{"6000/220",MODEL_RS220},
  1366. X                 {"6000/320H",MODEL_RS320H},{"6000/340",MODEL_RS340},
  1367. X                 {"6000/350",MODEL_RS350},{"6000/530H",MODEL_RS530H},
  1368. X                 {"6000/550",MODEL_RS550},{"6000/560",MODEL_RS560},
  1369. X                 {"6000/950",MODEL_RS950},
  1370. X                 {"?",0}};
  1371. X
  1372. X
  1373. X/******************************************************************************
  1374. X u_long netGetAddress(char *buf)
  1375. X
  1376. X This function coverts an internet hostname into an internet address (numeric
  1377. X format).  If no address can be found for the name, the hostname is checked to
  1378. X see if it is actually a numeric address in text form (e.g., "141.212.66.69").
  1379. X If it is, it is converted verbatim into numeric format.  If not, the return
  1380. X value is 0.  If multiple addresses are found for the host, the first one is
  1381. X returned.  The resulting IP address is given in network format.
  1382. X******************************************************************************/
  1383. X
  1384. X#ifdef __STDC__
  1385. Xu_long netGetAddress(char *buf)
  1386. X#else
  1387. Xu_long netGetAddress(buf)
  1388. Xchar *buf;
  1389. X#endif
  1390. X{
  1391. X     struct hostent *hp;
  1392. X     u_long addrbuf;
  1393. X     u_char ipaddr[4];
  1394. X     int i;
  1395. X     char temp[64],*p,*q,**cpp;
  1396. X
  1397. X#if (defined(MSDOS) && defined(NOVELL))
  1398. X     cpp=(&buf);
  1399. X     if ((addrbuf=rhost(cpp))==(-1)) {
  1400. X          perror("Getting server address");
  1401. X          addrbuf=(u_long)0;
  1402. X     }
  1403. X#else
  1404. X     hp=gethostbyname(buf);
  1405. X     if (hp==NULL) {
  1406. X          p=buf;
  1407. X          for (i=0; i<4; i++) {
  1408. X               q=temp;
  1409. X               while ((*p!='\0') && (*p!='.')) *(q++)=(*(p++));
  1410. X               *q='\0';
  1411. X               if (*p) ++p;
  1412. X               ipaddr[i]=(u_char)atoi(temp);
  1413. X          }
  1414. X          bcopy(ipaddr,&addrbuf,sizeof(addrbuf));
  1415. X     }
  1416. X     else {
  1417. X          if (hp->h_addr_list[0]!=NULL)
  1418. X               bcopy(hp->h_addr_list[0],&addrbuf,sizeof(addrbuf));
  1419. X          else addrbuf=0;
  1420. X     }
  1421. X#endif
  1422. X     return(addrbuf);
  1423. X}
  1424. X
  1425. X
  1426. X/******************************************************************************
  1427. X char *netGetHostname(u_long inaddr,char *buf)
  1428. X
  1429. X This function is the inverse of netGetAddress().  The IP address in network
  1430. X format stored in inaddr is converted to an internet hostname.  The resulting
  1431. X name is stored in the string pointed to by buf.  If no hostname can be found
  1432. X for the address, an ASCII representation of the IP address is returned (e.g.,
  1433. X "141.212.66.69").  A pointer to the name buffer (buf) is the return value.
  1434. X******************************************************************************/
  1435. X
  1436. X#ifdef __STDC__
  1437. Xchar *netGetHostname(u_long inaddr,char *buf)
  1438. X#else
  1439. Xchar *netGetHostname(inaddr,buf)
  1440. Xu_long inaddr;
  1441. Xchar *buf;
  1442. X#endif
  1443. X{
  1444. X     struct hostent *hp;
  1445. X     u_char ipbytes[4];
  1446. X     char *cp;
  1447. X
  1448. X#if (defined(MSDOS) && defined(NOVELL))
  1449. X     if ((cp=raddr(inaddr))==(char *)(-1)) {
  1450. X          bcopy((char *)&inaddr,ipbytes,sizeof(ipbytes));
  1451. X          sprintf(buf,"%d.%d.%d.%d",ipbytes[0],ipbytes[1],ipbytes[2],ipbytes[3]);
  1452. X     }
  1453. X     else strcpy(buf,cp);
  1454. X#else
  1455. X     hp=gethostbyaddr(&inaddr,sizeof(u_long),AF_INET);
  1456. X     if (hp==NULL) {
  1457. X          bcopy(&inaddr,ipbytes,sizeof(ipbytes));
  1458. X          sprintf(buf,"%d.%d.%d.%d",ipbytes[0],ipbytes[1],ipbytes[2],ipbytes[3]);
  1459. X     }
  1460. X     else strcpy(buf,hp->h_name);
  1461. X#endif
  1462. X     return(buf);
  1463. X}
  1464. X
  1465. X
  1466. X/******************************************************************************
  1467. X char *netGetMachType(u_char mtype,char *mtname)
  1468. X
  1469. X This function returns a text string representing the vendor type given by
  1470. X the mtype parameter, according to the MACH_xxx constants in netuse.h.  The
  1471. X resulting string is placed in the buffer pointed to by mtname, and a pointer
  1472. X to mtname is returned.  If mtype is not a valid machine type, the string "*"
  1473. X is returned.
  1474. X******************************************************************************/
  1475. X
  1476. X#ifdef __STDC__
  1477. Xchar *netGetMachType(u_char mtype,char *mtname)
  1478. X#else
  1479. Xchar *netGetMachType(mtype,mtname)
  1480. Xu_char mtype;
  1481. Xchar *mtname;
  1482. X#endif
  1483. X{
  1484. X     switch (mtype) {
  1485. X          case MACH_DEC:
  1486. X               strcpy(mtname,"DEC");
  1487. X               break;
  1488. X          case MACH_SUN:
  1489. X               strcpy(mtname,"Sun");
  1490. X               break;
  1491. X          case MACH_IBM_RS6000:
  1492. X               strcpy(mtname,"IBM");
  1493. X               break;
  1494. X          case MACH_APOLLO:
  1495. X               strcpy(mtname,"Apo");
  1496. X               break;
  1497. X          case MACH_HP:
  1498. X               strcpy(mtname,"HP ");
  1499. X               break;
  1500. X          default:
  1501. X               strcpy(mtname,"*");
  1502. X               break;
  1503. X     }
  1504. X     return(mtname);
  1505. X}
  1506. X
  1507. X
  1508. X/******************************************************************************
  1509. X This is the inverse of the netGetMachType() function.  It returns the numeric
  1510. X representation of the vendor name pointed to by mtname, according to the
  1511. X values given in netuse.h.  If the string is not a valid vendor type, the
  1512. X return value is 0.  The mtname string is treated case-insensitively.
  1513. X******************************************************************************/
  1514. X
  1515. X#ifdef __STDC__
  1516. Xu_char netStrToMach(char *mtname)
  1517. X#else
  1518. Xu_char netStrToMach(mtname)
  1519. Xchar *mtname;
  1520. X#endif
  1521. X{
  1522. X     char buf[128];
  1523. X
  1524. X     if (mtname==NULL) return(0);
  1525. X     strcpy(buf,mtname);
  1526. X     stoupper(buf);
  1527. X     if (!strcmp(buf,"SUN")) return(MACH_SUN);
  1528. X     if (!strcmp(buf,"DEC")) return(MACH_DEC);
  1529. X     if (!strcmp(buf,"IBM")) return(MACH_IBM_RS6000);
  1530. X     if (!strncmp(buf,"APO",3)) return(MACH_APOLLO);
  1531. X     if (!strncmp(buf,"HP",2)) return(MACH_HP);
  1532. X     return(0);
  1533. X}
  1534. X
  1535. X
  1536. X/******************************************************************************
  1537. X char *netGetModelType(u_char mtype,char *mtname)
  1538. X
  1539. X This function returns a text string representing the model type given by
  1540. X the mtype parameter, according to the MODEL_xxx constants in netuse.h.  The
  1541. X resulting string is placed in the buffer pointed to by mtname, and a pointer
  1542. X to mtname is returned.  If mtype is not a valid machine type, the string "*"
  1543. X is returned.
  1544. X******************************************************************************/
  1545. X
  1546. X#ifdef __STDC__
  1547. Xchar *netGetModelType(u_char mtype,char *mtname)
  1548. X#else
  1549. Xchar *netGetModelType(mtype,mtname)
  1550. Xu_char mtype;
  1551. Xchar *mtname;
  1552. X#endif
  1553. X{
  1554. X     MODELS *mptr;
  1555. X
  1556. X     if (mtname==NULL) return(NULL);
  1557. X     for (mptr=models; mptr->num && (mptr->num!=mtype); mptr++)
  1558. X          ;
  1559. X     strcpy(mtname,mptr->name);
  1560. X     return(mtname);
  1561. X}
  1562. X
  1563. X
  1564. X/******************************************************************************
  1565. X This is the inverse of the netGetModelType() function.  It returns the numeric
  1566. X representation of the model name pointed to by mtname, according to the
  1567. X values given in netuse.h.  If the string is not a valid vendor type, the
  1568. X return value is 0.  The mtname string is treated case-insensitively.
  1569. X******************************************************************************/
  1570. X
  1571. X#ifdef __STDC__
  1572. Xu_char netStrToModel(char *mtname)
  1573. X#else
  1574. Xu_char netStrToModel(mtname)
  1575. Xchar *mtname;
  1576. X#endif
  1577. X{
  1578. X     char buf[128];
  1579. X     MODELS *mptr;
  1580. X
  1581. X     if (mtname==NULL) return(0);
  1582. X     strcpy(buf,mtname);
  1583. X     stoupper(buf);
  1584. X     for (mptr=models; mptr->num && strcmp(buf,mptr->name); mptr++)
  1585. X          ;
  1586. X     return(mptr->num);
  1587. X}
  1588. X
  1589. X
  1590. X/******************************************************************************
  1591. X char *netuseFind(name,l1,l2,l3,users,console,tmp,machine,model)
  1592. X
  1593. X This function queries the NETUSE server for a machine which matches the
  1594. X parameters given.  The name of a matching machine is placed in the buffer
  1595. X pointed to by name, and a pointer to the buffer is returned.  If no host
  1596. X could be found, the name string is empty ("").  Network or server errors
  1597. X simply cause the return value to be the empty string.
  1598. X
  1599. X The following values give the "wildcard" values for each parameter.  If the
  1600. X parameter is set to the wildcard value, that parameter will not be used in
  1601. X selecting a host.
  1602. X
  1603. X    Parameter   Description                          Wildcard
  1604. X    ----------- ------------------------------------ --------
  1605. X    l1,l2,l3    Max load averages                      100.0
  1606. X    users       Max number of interactive sessions     100
  1607. X    console     Max console sessions                   100
  1608. X    tmp         Min /tmp free space (bytes)              0
  1609. X    machine     Machine (vendor) type                    0
  1610. X    model       Machine (model) type                     0
  1611. X******************************************************************************/
  1612. X
  1613. X#ifdef __STDC__
  1614. Xchar *netuseFind(char *name,double l1,double l2,double l3,int users,int console,
  1615. X                 int tmp,u_char machine,u_char model)
  1616. X#else
  1617. Xchar *netuseFind(name,l1,l2,l3,users,console,tmp,machine,model)
  1618. Xchar *name;
  1619. Xdouble l1,l2,l3;
  1620. Xint users,console,tmp;
  1621. Xu_char machine,model;
  1622. X#endif
  1623. X{
  1624. X     int rv,retry;
  1625. X     USEREC msg;
  1626. X
  1627. X     msg.opcode=OP_QUERY;
  1628. X     msg.load1=(u_short)(l1*100);
  1629. X     msg.load2=(u_short)(l2*100);
  1630. X     msg.load3=(u_short)(l3*100);
  1631. X     msg.users=(u_short)users;
  1632. X     msg.console=(u_short)console;
  1633. X     msg.tmp=(u_long)tmp;
  1634. X     msg.machine=machine;
  1635. X     msg.model=model;
  1636. X#if (defined(MSDOS) || defined(OS2))
  1637. X     msg.uid=0;
  1638. X#else
  1639. X     msg.uid=(u_short)getuid();
  1640. X#endif
  1641. X     if (rv=packetSend(&msg)) {
  1642. X          strcpy(name,"");
  1643. X          return(name);
  1644. X     }
  1645. X     retry=0;
  1646. X     while (rv=packetReceive(&msg)) {
  1647. X          switch (rv) {
  1648. X               case RV_nBADRECV:
  1649. X               case RV_nTIMEOUT:
  1650. X                    if ((++retry)>REQ_RETRIES) {
  1651. X                         strcpy(name,"");
  1652. X                         return(name);
  1653. X                    }
  1654. X                    msg.opcode=OP_QUERY;
  1655. X                    msg.load1=(u_short)(l1*100);
  1656. X                    msg.load2=(u_short)(l2*100);
  1657. X                    msg.load3=(u_short)(l3*100);
  1658. X                    msg.users=(u_short)users;
  1659. X                    msg.console=(u_short)console;
  1660. X                    msg.tmp=(u_long)tmp;
  1661. X                    msg.machine=machine;
  1662. X                    msg.model=model;
  1663. X                    packetSend(&msg);
  1664. X                    break;
  1665. X          }
  1666. X     }
  1667. X     if (msg.retcode==RV_OK) {
  1668. X          msg.ipaddr=htonl(msg.ipaddr);   /* Put back into network order */
  1669. X          return(netGetHostname(msg.ipaddr,name));
  1670. X     }
  1671. X     else {
  1672. X          strcpy(name,"");
  1673. X          return(name);
  1674. X     }
  1675. X}
  1676. END_OF_FILE
  1677.   if test 13002 -ne `wc -c <'netuse/lib/gethost.c'`; then
  1678.     echo shar: \"'netuse/lib/gethost.c'\" unpacked with wrong size!
  1679.   fi
  1680.   # end of 'netuse/lib/gethost.c'
  1681. fi
  1682. echo shar: End of archive 2 \(of 6\).
  1683. cp /dev/null ark2isdone
  1684. MISSING=""
  1685. for I in 1 2 3 4 5 6 ; do
  1686.     if test ! -f ark${I}isdone ; then
  1687.     MISSING="${MISSING} ${I}"
  1688.     fi
  1689. done
  1690. if test "${MISSING}" = "" ; then
  1691.     echo You have unpacked all 6 archives.
  1692.     rm -f ark[1-9]isdone
  1693. else
  1694.     echo You still must unpack the following archives:
  1695.     echo "        " ${MISSING}
  1696. fi
  1697. exit 0
  1698. exit 0 # Just in case...
  1699.