home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / netuse / part02 < prev    next >
Encoding:
Text File  |  1993-01-09  |  50.0 KB  |  1,693 lines

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