|
|
1.1 ! root 1: /* xwho.c - who for X windows */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/others/image/RCS/xwho.c,v 7.0 89/11/23 22:00:06 mrose Rel $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/others/image/RCS/xwho.c,v 7.0 89/11/23 22:00:06 mrose Rel $ ! 9: * ! 10: * ! 11: * $Log: xwho.c,v $ ! 12: * Revision 7.0 89/11/23 22:00:06 mrose ! 13: * Release 6.0 ! 14: * ! 15: */ ! 16: ! 17: /* ! 18: * NOTICE ! 19: * ! 20: * Acquisition, use, and distribution of this module and related ! 21: * materials are subject to the restrictions of a license agreement. ! 22: * Consult the Preface in the User's Manual for the full terms of ! 23: * this agreement. ! 24: * ! 25: */ ! 26: ! 27: ! 28: #include <stdio.h> ! 29: #include "imagesbr.h" ! 30: #include <X11/Xlib.h> ! 31: #include <X11/Xutil.h> ! 32: #include "rwhod.h" ! 33: #include <netdb.h> ! 34: #include <sys/file.h> ! 35: #include "usr.dirent.h" ! 36: ! 37: ! 38: #define NHOSTS 100 ! 39: ! 40: /* DATA */ ! 41: ! 42: int debug = 0; ! 43: int errsw = 0; ! 44: static int sleepsw = 60; ! 45: ! 46: static char *host_list[NHOSTS + 1]; /* Hosts to (not) list */ ! 47: static char **host_end = host_list; ! 48: static int dont_list = 0; ! 49: ! 50: static char *myname = "xwho"; ! 51: ! 52: ! 53: static char *display = NULL; ! 54: static char *geometry = NULL; ! 55: ! 56: /* */ ! 57: ! 58: typedef struct _frame { ! 59: short x, y; ! 60: unsigned int width, height; ! 61: unsigned int bdrwidth; ! 62: unsigned long border; ! 63: unsigned long background; ! 64: } OpaqueFrame; ! 65: ! 66: static Display *DISP; ! 67: static int SCRN; ! 68: ! 69: static int mapped; ! 70: ! 71: static Window mywindow; ! 72: static OpaqueFrame myframe; ! 73: ! 74: static char *fontname = "6x10"; ! 75: static XFontStruct *myfont; ! 76: ! 77: static int bwidth; ! 78: static XSizeHints hints; ! 79: static XSetWindowAttributes xswattrs; ! 80: static unsigned long xswattrs_mask; ! 81: ! 82: static unsigned long backpix, bdrpix; ! 83: static GC forepix, highpix; ! 84: ! 85: ! 86: struct face { ! 87: char f_name[8 + 1]; ! 88: int f_active; ! 89: ! 90: int f_update; ! 91: Window f_window; ! 92: OpaqueFrame f_frame; ! 93: ! 94: struct type_IMAGE_Image *f_imap; ! 95: ! 96: struct face *f_next; ! 97: }; ! 98: ! 99: ! 100: struct host { ! 101: char h_name[32 + 1]; ! 102: int h_up; ! 103: ! 104: int h_update; ! 105: char h_string[32 + 2]; ! 106: Window h_window; ! 107: GC h_gc; ! 108: int h_ascent; ! 109: OpaqueFrame h_frame; ! 110: ! 111: struct face *h_faces; ! 112: ! 113: struct host *h_next; ! 114: }; ! 115: ! 116: static int largest_h, largest_w; ! 117: ! 118: static struct host *hosts; ! 119: ! 120: ! 121: long time (); ! 122: ! 123: /* MAIN */ ! 124: ! 125: /* ARGSUSED */ ! 126: ! 127: main (argc, argv, envp) ! 128: int argc; ! 129: char **argv, ! 130: **envp; ! 131: { ! 132: int nfds; ! 133: fd_set rfds; ! 134: ! 135: arginit (argv); ! 136: ! 137: if (errsw) ! 138: errsw = NOTOK; ! 139: ! 140: update_X (); ! 141: ! 142: FD_ZERO (&rfds); ! 143: nfds = ConnectionNumber (DISP) + 1; ! 144: FD_SET (ConnectionNumber (DISP), &rfds); ! 145: for (;;) { ! 146: fd_set ifds; ! 147: ! 148: ifds = rfds; ! 149: (void) xselect (nfds, &ifds, NULLFD, NULLFD, sleepsw); ! 150: ! 151: update_X (); ! 152: } ! 153: } ! 154: ! 155: /* ARGINIT */ ! 156: ! 157: arginit (vec) ! 158: char **vec; ! 159: { ! 160: int n, ! 161: nhosts; ! 162: register char *ap, ! 163: *cp, ! 164: *lp; ! 165: register struct hostent *hp; ! 166: ! 167: if (myname = rindex (*vec, '/')) ! 168: myname++; ! 169: if (myname == NULL || *myname == NULL) ! 170: myname = *vec; ! 171: ! 172: isodetailor (myname, 1); ! 173: lp = NULL; ! 174: ! 175: nhosts = 0; ! 176: for (vec++; ap = *vec; vec++) ! 177: if (*ap == '-') ! 178: switch (*++ap) { ! 179: case 'd': ! 180: debug++; ! 181: break; ! 182: ! 183: case 'e': ! 184: errsw++; ! 185: break; ! 186: ! 187: case 'l': ! 188: if ((lp = *++vec) == NULL) ! 189: adios (NULLCP, "usage: %s -h local_dit", myname); ! 190: break; ! 191: ! 192: case 'r': ! 193: recording++; ! 194: break; ! 195: ! 196: case 's': ! 197: if ((ap = *++vec) == NULL ! 198: || sscanf (ap, "%d", &sleepsw) != 1 ! 199: || sleepsw < 1) ! 200: adios (NULLCP, "usage: %s -s seconds", myname); ! 201: break; ! 202: ! 203: case 'n': ! 204: dont_list++; ! 205: break; ! 206: ! 207: default: ! 208: adios (NULLCP, "unknown switch -%s", ap); ! 209: } ! 210: else ! 211: if (*ap == '=') ! 212: geometry = ap; ! 213: else ! 214: if ((cp = rindex (ap, ':')) && sscanf (++cp, "%d", &n) == 1) ! 215: display = ap; ! 216: else { ! 217: if (nhosts++ >= NHOSTS) ! 218: adios (NULLCP, "too many hosts"); ! 219: ! 220: if ((hp = gethostbyname (ap)) == NULL) ! 221: adios (NULLCP, "%s: unknown host", ap); ! 222: if ((ap = malloc ((unsigned) (strlen (hp -> h_name) + 1))) ! 223: == NULL) ! 224: adios (NULLCP, "out of memory"); ! 225: ! 226: (void) strcpy (*host_end++ = ap, hp -> h_name); ! 227: } ! 228: ! 229: init_aka (myname, 1, lp); ! 230: ! 231: if (debug) ! 232: ll_dbinit (pgm_log, myname); ! 233: else ! 234: ll_hdinit (pgm_log, myname); ! 235: (void) ll_open (pgm_log); ! 236: ! 237: if ((DISP = XOpenDisplay (display)) == NULL) ! 238: adios (NULLCP, "unable to open display \"%s\"", ! 239: XDisplayName (display)); ! 240: SCRN = DefaultScreen (DISP); ! 241: ! 242: forepix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, (XGCValues *)NULL); ! 243: highpix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, (XGCValues *)NULL); ! 244: XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, forepix); ! 245: XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, highpix); ! 246: if ((cp = XGetDefault (DISP, myname, "ReverseVideo")) ! 247: && strcmp (cp, "on") == 0) { ! 248: XSetForeground(DISP, forepix, WhitePixel(DISP, SCRN)); ! 249: XSetForeground(DISP, highpix, WhitePixel(DISP, SCRN)); ! 250: backpix = BlackPixel(DISP, SCRN); ! 251: bdrpix = WhitePixel(DISP, SCRN); ! 252: XSetFunction(DISP, forepix, GXcopyInverted); ! 253: XSetFunction(DISP, highpix, GXand); ! 254: } ! 255: else { ! 256: XSetForeground(DISP, forepix, BlackPixel(DISP, SCRN)); ! 257: XSetForeground(DISP, highpix, BlackPixel(DISP, SCRN)); ! 258: backpix = WhitePixel(DISP, SCRN); ! 259: bdrpix = BlackPixel(DISP, SCRN); ! 260: XSetFunction(DISP, forepix, GXcopy); ! 261: XSetFunction(DISP, highpix, GXor); ! 262: } ! 263: ! 264: XSetBackground (DISP, forepix, backpix); ! 265: XSetBackground (DISP, highpix, backpix); ! 266: ! 267: if (cp = XGetDefault (DISP, myname, "BorderWidth")) ! 268: bwidth = atoi (cp); ! 269: else ! 270: bwidth = 2; ! 271: ! 272: if (cp = XGetDefault (DISP, myname, "BodyFont")) ! 273: fontname = cp; ! 274: myfont = XLoadQueryFont (DISP, fontname); ! 275: } ! 276: ! 277: /* XWINDOWS */ ! 278: ! 279: static update_X () ! 280: { ! 281: register struct host *hp; ! 282: register struct face *fp; ! 283: XGCValues gcvalues; ! 284: ! 285: service_X (); ! 286: ! 287: if (mywindow && !mapped) ! 288: return; ! 289: ! 290: read_X (); ! 291: ! 292: layout_X (); ! 293: ! 294: if (mywindow == NULL) ! 295: init_X (); ! 296: ! 297: for (hp = hosts; hp; hp = hp -> h_next) { ! 298: if (hp -> h_update && display_this_host (hp -> h_name)) { ! 299: if (hp -> h_window) { ! 300: XFreeGC (DISP, hp -> h_gc); ! 301: XDestroyWindow (DISP, hp -> h_window); ! 302: } ! 303: ! 304: if (debug) ! 305: fprintf (stderr, "%s: %dx%d+%d+%d/%d\n", ! 306: hp -> h_name, hp -> h_frame.width, ! 307: hp -> h_frame.height, hp -> h_frame.x, ! 308: hp -> h_frame.y, hp -> h_frame.bdrwidth); ! 309: hp -> h_window = XCreateSimpleWindow (DISP, mywindow, ! 310: hp -> h_frame.x, ! 311: hp -> h_frame.y, ! 312: hp -> h_frame.width, ! 313: hp -> h_frame.height, ! 314: hp -> h_frame.bdrwidth, ! 315: hp -> h_frame.border, ! 316: hp -> h_frame.background); ! 317: ! 318: XSelectInput (DISP, hp -> h_window, ExposureMask); ! 319: ! 320: XMapWindow (DISP, hp -> h_window); ! 321: ! 322: gcvalues.foreground = bdrpix; ! 323: gcvalues.background = backpix; ! 324: gcvalues.font = myfont -> fid; ! 325: hp -> h_gc = XCreateGC (DISP, hp -> h_window, ! 326: GCForeground | GCBackground | GCFont, ! 327: &gcvalues); ! 328: } ! 329: ! 330: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 331: if (fp -> f_update) { ! 332: if (fp -> f_window) ! 333: XDestroyWindow (DISP, fp -> f_window); ! 334: ! 335: if (debug) ! 336: fprintf (stderr, "%s: %dx%d+%d+%d/%d\n", ! 337: fp -> f_name, fp -> f_frame.width, ! 338: fp -> f_frame.height, fp -> f_frame.x, ! 339: fp -> f_frame.y, fp -> f_frame.bdrwidth); ! 340: fp -> f_window = XCreateSimpleWindow(DISP, mywindow, ! 341: fp -> f_frame.x, ! 342: fp -> f_frame.y, ! 343: fp -> f_frame.width, ! 344: fp -> f_frame.height, ! 345: fp -> f_frame.bdrwidth, ! 346: fp -> f_frame.border, ! 347: fp -> f_frame.background); ! 348: ! 349: XSelectInput (DISP, fp -> f_window, ExposureMask); ! 350: ! 351: XMapWindow (DISP, fp -> f_window); ! 352: } ! 353: } ! 354: ! 355: service_X (); ! 356: } ! 357: ! 358: /* */ ! 359: ! 360: static int service_X () ! 361: { ! 362: int wh, ! 363: ww; ! 364: register Window w; ! 365: register struct face *fp; ! 366: register struct host *hp; ! 367: XEvent xevent; ! 368: register XEvent *xe = &xevent; ! 369: ! 370: while (XPending (DISP)) { ! 371: XNextEvent (DISP, xe); ! 372: ! 373: switch (xe -> type) { ! 374: case Expose: ! 375: if ((w = ((XExposeEvent *) xe) -> window) == mywindow) { ! 376: display_top (); ! 377: break; ! 378: } ! 379: ! 380: for (hp = hosts; hp; hp = hp -> h_next) { ! 381: if (!display_this_host (hp -> h_name)) ! 382: continue; ! 383: ! 384: if (hp -> h_window == w) { ! 385: display_host (hp); ! 386: break; ! 387: } ! 388: ! 389: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 390: if (fp -> f_window == w) ! 391: break; ! 392: if (fp) { ! 393: display_face (fp); ! 394: break; ! 395: } ! 396: } ! 397: break; ! 398: ! 399: case MapNotify: ! 400: if (debug) ! 401: fprintf (stderr, "MapNotify\n"); ! 402: mapped = 1; ! 403: display_top (); ! 404: break; ! 405: ! 406: case ConfigureNotify: ! 407: if (debug) ! 408: fprintf (stderr, "ConfigureNotify %dx%d\n", ! 409: ((XConfigureEvent *) xe) -> height, ! 410: ((XConfigureEvent *) xe) -> width); ! 411: if (((XConfigureEvent *) xe) -> window == mywindow ! 412: && (wh = ((XConfigureEvent *) xe) -> height) > 0 ! 413: && (ww = ((XConfigureEvent *) xe) -> width) > 0) ! 414: myframe.height = wh, myframe.width = ww; ! 415: break; ! 416: ! 417: case UnmapNotify: ! 418: if (debug) ! 419: fprintf (stderr, "UnmapNotify\n"); ! 420: mapped = 0; ! 421: break; ! 422: ! 423: case ReparentNotify: ! 424: if (debug) ! 425: fprintf (stderr, "ReparentNotify\n"); ! 426: break; ! 427: ! 428: default: ! 429: if (debug) ! 430: fprintf (stderr, "Event %d\n", xe -> type); ! 431: break; ! 432: } ! 433: } ! 434: } ! 435: ! 436: /* */ ! 437: ! 438: static init_X () ! 439: { ! 440: char def[BUFSIZ]; ! 441: ! 442: myframe.bdrwidth = bwidth; ! 443: myframe.height = largest_h + 100; ! 444: if (myframe.height + bwidth * 2 > DisplayHeight (DISP, SCRN)) ! 445: myframe.height = DisplayHeight (DISP, SCRN) - bwidth * 2; ! 446: myframe.width = largest_w + 100; ! 447: if (myframe.width + bwidth * 2 > DisplayWidth (DISP, SCRN)) ! 448: myframe.width = DisplayWidth (DISP, SCRN) - bwidth * 2; ! 449: myframe.x = DisplayWidth (DISP, SCRN) - (myframe.width + bwidth * 2); ! 450: myframe.y = 0; ! 451: (void) sprintf (def, "=%dx%d+%d+%d", myframe.width, myframe.height, ! 452: myframe.x, myframe.y); ! 453: ! 454: if (debug) ! 455: fprintf (stderr, "def: %s, myframe: =%dx%d+%d+%d/%d\n", def, ! 456: myframe.width, myframe.height, myframe.x, myframe.y, ! 457: myframe.bdrwidth); ! 458: ! 459: hints.width = largest_w + 100; ! 460: hints.height = largest_h + 100; ! 461: hints.x = hints.y = 0; ! 462: hints.flags = PSize | PPosition; ! 463: ! 464: xswattrs.border_pixel = bdrpix; ! 465: xswattrs.background_pixel = backpix; ! 466: xswattrs_mask = CWBackPixel | CWBorderPixel; ! 467: ! 468: mywindow = XCreateWindow (DISP, RootWindow (DISP, SCRN), ! 469: myframe.x, myframe.y, ! 470: myframe.width, myframe.height, ! 471: myframe.bdrwidth, ! 472: 0, InputOutput, (Visual *) CopyFromParent, ! 473: xswattrs_mask, &xswattrs); ! 474: ! 475: XSetStandardProperties (DISP, mywindow, myname, "X Who", None, ! 476: (char **) 0, 0, &hints); ! 477: ! 478: XSelectInput (DISP, mywindow, ExposureMask | StructureNotifyMask); ! 479: ! 480: XMapWindow (DISP, mywindow); ! 481: mapped = 0; ! 482: } ! 483: ! 484: /* */ ! 485: ! 486: static layout_X () ! 487: { ! 488: int h; ! 489: register struct face *fp; ! 490: register struct host *hp; ! 491: XCharStruct mychar; ! 492: ! 493: h = largest_w = 0; ! 494: ! 495: for (hp = hosts; hp; hp = hp -> h_next) { ! 496: int hh, ! 497: hw; ! 498: ! 499: hh = hw = 0; ! 500: if (hp -> h_window == NULL || hp -> h_frame.y != h) { ! 501: int direction_return, ! 502: font_ascent_return, ! 503: font_descent_return; ! 504: ! 505: hp -> h_frame.bdrwidth = 2; ! 506: XTextExtents (myfont, hp -> h_string, strlen (hp -> h_string), ! 507: &direction_return, &font_ascent_return, ! 508: &font_descent_return, &mychar); ! 509: hp -> h_ascent = mychar.ascent; ! 510: hp -> h_frame.height = mychar.ascent + mychar.descent; ! 511: hp -> h_frame.border = backpix; ! 512: hp -> h_frame.background = backpix; ! 513: hp -> h_frame.x = 0; ! 514: hp -> h_frame.y = h; ! 515: hp -> h_update = 1; ! 516: } ! 517: else ! 518: hp -> h_update = 0; ! 519: h += hp -> h_frame.height + 2 * hp -> h_frame.bdrwidth; ! 520: ! 521: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 522: if (fp -> f_imap && fp -> f_imap -> height > hh) ! 523: hh = fp -> f_imap -> height; ! 524: ! 525: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 526: if (fp -> f_imap) { ! 527: if (fp -> f_window == NULL ! 528: || fp -> f_frame.height != hh ! 529: || fp -> f_frame.width != fp -> f_imap -> width ! 530: || fp -> f_frame.x != hw ! 531: || fp -> f_frame.y != h) { ! 532: fp -> f_frame.bdrwidth = bwidth; ! 533: fp -> f_frame.height = hh; ! 534: fp -> f_frame.width = fp -> f_imap -> width; ! 535: fp -> f_frame.border = backpix; ! 536: fp -> f_frame.background = backpix; ! 537: fp -> f_frame.x = hw; ! 538: fp -> f_frame.y = h; ! 539: ! 540: fp -> f_update = 1; ! 541: } ! 542: else ! 543: fp -> f_update = 0; ! 544: ! 545: hw += fp -> f_imap -> width + bwidth * 2; ! 546: } ! 547: else ! 548: fp -> f_update = 0; ! 549: if (hw > largest_w) ! 550: largest_w = hw; ! 551: if (hp -> h_frame.width > largest_w) ! 552: largest_w = hp -> h_frame.width; ! 553: ! 554: if (hw > 0) ! 555: h += hh + 2; ! 556: else { ! 557: h -= hp -> h_frame.height + 2 * hp -> h_frame.bdrwidth; ! 558: hp -> h_update = 0; ! 559: if (hp -> h_window) { ! 560: XFreeGC (DISP, hp -> h_gc); ! 561: XDestroyWindow (DISP, hp -> h_window); ! 562: hp -> h_window = NULL; ! 563: } ! 564: } ! 565: } ! 566: ! 567: largest_h = h; ! 568: } ! 569: ! 570: /* */ ! 571: ! 572: static display_top () ! 573: { ! 574: if (debug) ! 575: fprintf (stderr, "top window\n"); ! 576: } ! 577: ! 578: ! 579: static display_host (hp) ! 580: register struct host *hp; ! 581: { ! 582: if (debug) ! 583: fprintf (stderr, "%s:\n", hp -> h_name); ! 584: ! 585: XDrawImageString (DISP, hp -> h_window, hp -> h_gc, 0, hp -> h_ascent, ! 586: hp -> h_string, strlen (hp -> h_string)); ! 587: } ! 588: ! 589: /* */ ! 590: ! 591: static display_face (fp) ! 592: register struct face *fp; ! 593: { ! 594: int sx, ! 595: sy, ! 596: dx, ! 597: dy; ! 598: unsigned int h, ! 599: w; ! 600: register struct type_IMAGE_Image *im = fp -> f_imap; ! 601: register OpaqueFrame *xm = &fp -> f_frame; ! 602: XImage *image; ! 603: ! 604: sx = max (im -> width - (int) xm -> width, 0) / 2; ! 605: sy = max (im -> height - (int) xm -> height, 0) / 2; ! 606: dx = max ((int) xm -> width - im -> width, 0) / 2; ! 607: dy = max ((int) xm -> height - im -> height, 0) / 2; ! 608: w = min (xm -> width, im -> width); ! 609: h = min (xm -> height, im -> height); ! 610: ! 611: if (debug) { ! 612: fprintf (stderr, "im: %dx%d frame:%dx%d\n", ! 613: im -> width, im -> height, xm -> width, xm -> height); ! 614: fprintf (stderr, "sx=%d sy=%d dx=%d dy=%d w=%d h=%d\n", ! 615: sx, sy, dx, dy, w, h); ! 616: } ! 617: ! 618: image = XCreateImage (DISP, DefaultVisual (DISP, SCRN), 1, XYBitmap, 0, ! 619: im -> data -> qb_forw -> qb_data, ! 620: (unsigned int) im -> width, ! 621: (unsigned int) im -> height, 8, 0); ! 622: if (image == NULL) ! 623: adios (NULLCP, "XCreateImage failed"); ! 624: image -> byte_order = image -> bitmap_bit_order = LSBFirst; ! 625: XClearWindow (DISP, fp -> f_window); ! 626: XPutImage (DISP, fp -> f_window, forepix, image, sx, sy, dx, dy, w, h); ! 627: ! 628: XDestroyImage (image); ! 629: } ! 630: ! 631: /* */ ! 632: ! 633: static int facecmp (f1, f2) ! 634: struct face **f1, ! 635: **f2; ! 636: { ! 637: return strcmp ((*f1) -> f_name, (*f2) -> f_name); ! 638: } ! 639: ! 640: ! 641: static int hostcmp (h1, h2) ! 642: struct host **h1, ! 643: **h2; ! 644: { ! 645: return strcmp ((*h1) -> h_name, (*h2) -> h_name); ! 646: } ! 647: ! 648: ! 649: static read_X () ! 650: { ! 651: int fd, ! 652: n; ! 653: long now; ! 654: register struct dirent *dp; ! 655: register struct face *fp, ! 656: **fpp; ! 657: register struct host *hp, ! 658: **hpp; ! 659: struct whod wds; ! 660: register struct whod *wd = &wds; ! 661: register struct whoent *we; ! 662: static DIR *dd = NULL; ! 663: ! 664: (void) time (&now); ! 665: for (hp = hosts; hp; hp = hp -> h_next) { ! 666: hp -> h_up = 0; ! 667: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 668: fp -> f_active = 0; ! 669: } ! 670: ! 671: if (dd == NULL) { ! 672: if (chdir ("/usr/spool/rwho") == NOTOK) ! 673: adios ("/usr/spool/rwho", "unable to change directory to"); ! 674: ! 675: if ((dd = opendir (".")) == NULL) ! 676: adios ("/usr/spool/rwho", "unable to read"); ! 677: } ! 678: else ! 679: rewinddir (dd); ! 680: ! 681: while (dp = readdir (dd)) { ! 682: if (dp -> d_ino == 0 || strncmp (dp -> d_name, "whod.", 5) != 0) ! 683: continue; ! 684: ! 685: if ((fd = open (dp -> d_name, O_RDONLY)) == NOTOK) ! 686: continue; ! 687: n = read (fd, (char *) wd, sizeof *wd); ! 688: (void) close (fd); ! 689: if ((n -= sizeof *wd - sizeof wd -> wd_we) < 0) ! 690: continue; ! 691: ! 692: if (now - wd -> wd_recvtime > 5 * 60 || n < sizeof *we) ! 693: continue; ! 694: ! 695: for (hp = hosts; hp; hp = hp -> h_next) ! 696: if (strncmp (hp -> h_name, wd -> wd_hostname, ! 697: sizeof wd -> wd_hostname) == 0) ! 698: break; ! 699: if (hp == NULL) { ! 700: if ((hp = (struct host *) calloc (1, sizeof *hp)) == NULL) ! 701: adios (NULLCP, "out of memory"); ! 702: hp -> h_next = hosts; ! 703: hosts = hp; ! 704: ! 705: (void) strncpy (hp -> h_name, wd -> wd_hostname, ! 706: sizeof wd -> wd_hostname); ! 707: (void) sprintf (hp -> h_string, "%s:", hp -> h_name); ! 708: hp -> h_frame.width = XTextWidth (myfont, hp -> h_string, ! 709: strlen (hp -> h_string)); ! 710: } ! 711: ! 712: hp -> h_up = 1; ! 713: ! 714: for (we = wd -> wd_we, n = n / sizeof *we; n > 0; we++, n--) { ! 715: if (we -> we_idle > 60 * 60) ! 716: continue; ! 717: ! 718: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 719: if (strncmp (fp -> f_name, we -> we_utmp.out_name, ! 720: sizeof we -> we_utmp.out_name) == 0) ! 721: break; ! 722: if (fp == NULL) { ! 723: if ((fp = (struct face *) calloc (1, sizeof *fp)) == NULL) ! 724: adios (NULLCP, "out of memory"); ! 725: fp -> f_next = hp -> h_faces; ! 726: hp -> h_faces = fp; ! 727: ! 728: (void) strncpy (fp -> f_name, we -> we_utmp.out_name, ! 729: sizeof we -> we_utmp.out_name); ! 730: ! 731: if (display_this_host (hp -> h_name) ! 732: && (fp -> f_imap = fetch_image (fp -> f_name, NULLCP)) ! 733: == NULL) { ! 734: if (recording) ! 735: LLOG (pgm_log, LLOG_NOTICE, ! 736: ("no image for \"%s\" \"%s\"", ! 737: hp -> h_name, fp -> f_name)); ! 738: } ! 739: } ! 740: ! 741: fp -> f_active = 1; ! 742: } ! 743: } ! 744: ! 745: for (hpp = &hosts; hp = *hpp;) { ! 746: for (fpp = &hp -> h_faces; fp = *fpp;) { ! 747: if (!hp -> h_up || !fp -> f_active) { ! 748: *fpp = fp -> f_next; ! 749: if (fp -> f_window) ! 750: XDestroyWindow (DISP, fp -> f_window); ! 751: free ((char *) fp); ! 752: continue; ! 753: } ! 754: ! 755: fpp = &fp -> f_next; ! 756: } ! 757: ! 758: if (!hp -> h_up || hp -> h_faces == NULL) { ! 759: *hpp = hp -> h_next; ! 760: if (hp -> h_window) { ! 761: XFreeGC (DISP, hp -> h_gc); ! 762: XDestroyWindow (DISP, hp -> h_window); ! 763: } ! 764: free ((char *) hp); ! 765: } ! 766: else ! 767: hpp = &hp -> h_next; ! 768: } ! 769: ! 770: { ! 771: register int i; ! 772: register struct host **hq; ! 773: ! 774: i = 0; ! 775: for (hp = hosts; hp; hp = hp -> h_next) { ! 776: register int j; ! 777: register struct face **fq; ! 778: ! 779: i++, j = 0; ! 780: for (fp = hp -> h_faces; fp; fp = fp -> f_next) ! 781: j++; ! 782: if (j > 1) { ! 783: register struct face **faces; ! 784: ! 785: if ((faces = (struct face **) ! 786: calloc ((unsigned) j, sizeof *faces)) == NULL) ! 787: continue; ! 788: for (fp = hp -> h_faces, fq = faces; ! 789: *fq = fp; ! 790: fp = fp -> f_next, fq++) ! 791: continue; ! 792: qsort ((char *) faces, j, sizeof *faces, facecmp); ! 793: for (fq = faces, fpp = &hp -> h_faces; ! 794: *fpp = *fq; ! 795: fq++, fpp = &(*fpp) -> f_next) ! 796: continue; ! 797: ! 798: free ((char *) faces); ! 799: } ! 800: } ! 801: ! 802: if (i > 1) { ! 803: register struct host **hostz; ! 804: ! 805: if ((hostz = (struct host **) ! 806: calloc ((unsigned) i, sizeof *hostz)) == NULL) ! 807: goto out; ! 808: for (hp = hosts, hq = hostz; *hq = hp; hp = hp -> h_next, hq++) ! 809: continue; ! 810: qsort ((char *) hostz, i, sizeof *hostz, hostcmp); ! 811: for (hq = hostz, hpp = &hosts; ! 812: *hpp = *hq; ! 813: hq++, hpp = &(*hpp) -> h_next) ! 814: continue; ! 815: ! 816: free ((char *) hostz); ! 817: } ! 818: } ! 819: ! 820: out: ; ! 821: } ! 822: ! 823: /* */ ! 824: ! 825: static int display_this_host (n) ! 826: register char *n; ! 827: { ! 828: register char **ap; ! 829: ! 830: if (host_list == host_end) ! 831: return 1; ! 832: ! 833: for (ap = host_list; ap < host_end; ap++) ! 834: if (strcmp (*ap, n) == 0) ! 835: return (!dont_list); ! 836: ! 837: return dont_list; ! 838: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.