ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/root-tail/root-tail.c
(Generate patch)

Comparing root-tail/root-tail.c (file contents):
Revision 1.27 by chris_moore, Mon Mar 29 02:20:55 2004 UTC vs.
Revision 1.47 by pcg, Thu Apr 1 13:37:30 2004 UTC

1/* 1/*
2 * Copyright 2001 by Marco d'Itri <md@linux.it> 2 * Copyright 2001 by Marco d'Itri <md@linux.it>
3 * 3 * Copyright 2000,2001,2002,2003,2004
4 * Original version by Mike Baker, then maintained by pcg@goof.com. 4 * Marc Lehmann <pcg@goof.com>,
5 * and many others, see README
6 *
7 * Original version by Mike Baker.
5 * 8 *
6 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 12 * (at your option) any later version.
57 off_t last_size; /* file size at the last check */ 60 off_t last_size; /* file size at the last check */
58 unsigned long color; /* color to be used for printing */ 61 unsigned long color; /* color to be used for printing */
59 int partial; /* true if the last line isn't complete */ 62 int partial; /* true if the last line isn't complete */
60 int lastpartial; /* true if the previous output wasn't complete */ 63 int lastpartial; /* true if the previous output wasn't complete */
61 int index; /* index into linematrix of a partial line */ 64 int index; /* index into linematrix of a partial line */
65 int modified; /* true if line is modified & needs displaying */
62}; 66};
63 67
64struct linematrix 68struct linematrix
65{ 69{
66 char *line; 70 char *line;
67 int len; 71 int len;
68 unsigned long color; 72 unsigned long color;
69}; 73};
70 74
75struct displaymatrix
76{
77 char *line;
78 int len;
79 int buffer_size;
80 unsigned long color;
81};
82
71/* global variables */ 83/* global variables */
72struct linematrix *lines; 84struct linematrix *lines;
85struct displaymatrix *display;
73int width = STD_WIDTH, height = STD_HEIGHT, listlen; 86int width = STD_WIDTH, height = STD_HEIGHT, listlen;
74int win_x = LOC_X, win_y = LOC_Y; 87int win_x = LOC_X, win_y = LOC_Y;
75int font_ascent, font_height; 88int font_ascent, font_height;
76int effect_x_space, effect_y_space; /* how much space does shading / outlining take up */ 89int effect_x_space, effect_y_space; /* how much space does shading / outlining take up */
77int effect_x_offset, effect_y_offset; /* and how does it offset the usable space */ 90int effect_x_offset, effect_y_offset; /* and how does it offset the usable space */
112void force_refresh (int); 125void force_refresh (int);
113void blank_window (int); 126void blank_window (int);
114 127
115void InitWindow (void); 128void InitWindow (void);
116unsigned long GetColor (const char *); 129unsigned long GetColor (const char *);
117void redraw (void); 130void redraw (int);
118void refresh (int, int, int); 131void refresh (int, int, int, int);
119 132
120void transform_line (char *s); 133void transform_line (char *s);
121int lineinput (struct logfile_entry *); 134int lineinput (struct logfile_entry *);
122void reopen (void); 135void reopen (void);
123void check_open_files (void); 136void check_open_files (void);
127void display_version (void); 140void display_version (void);
128void display_help (char *); 141void display_help (char *);
129void install_signal (int, void (*)(int)); 142void install_signal (int, void (*)(int));
130void *xstrdup (const char *); 143void *xstrdup (const char *);
131void *xmalloc (size_t); 144void *xmalloc (size_t);
145void *xrealloc (void *, size_t);
132int daemonize (void); 146int daemonize (void);
133 147
134/* signal handlers */ 148/* signal handlers */
135void 149void
136list_files (int dummy) 150list_files (int dummy)
149} 163}
150 164
151void 165void
152force_refresh (int dummy) 166force_refresh (int dummy)
153{ 167{
154 redraw (); 168 redraw (1);
155} 169}
156 170
157void 171void
158blank_window (int dummy) 172blank_window (int dummy)
159{ 173{
348 362
349 XSelectInput (disp, root, ExposureMask | FocusChangeMask); 363 XSelectInput (disp, root, ExposureMask | FocusChangeMask);
350} 364}
351 365
352/* 366/*
353 * redraw does a complete redraw, rather than an update (i.e. the area 367 * if redraw() is passwd a non-zero argument, it does a complete
354 * gets cleared first) 368 * redraw, rather than an update. if the argument is zero (and
369 * -noflicker is in effect) then only the lines which have changed
370 * since the last draw are redrawn.
371 *
355 * the rest is handled by regular refresh()'es 372 * the rest is handled by regular refresh()'es
356 */ 373 */
357void 374void
358redraw (void) 375redraw (int redraw_all)
359{ 376{
360 XSetClipMask (disp, WinGC, None); 377 XSetClipMask (disp, WinGC, None);
361 refresh (0, 32768, 1); 378 refresh (0, 32768, 1, redraw_all);
362} 379}
363 380
364/* Just redraw everything without clearing (i.e. after an EXPOSE event) */ 381/* Just redraw everything without clearing (i.e. after an EXPOSE event) */
365void 382void
366refresh (int miny, int maxy, int clear) 383refresh (int miny, int maxy, int clear, int refresh_all)
367{ 384{
368 int lin; 385 int lin;
369 int offset = (listlen + 1) * font_height; 386 int offset = listlen * font_height + font_ascent + effect_y_offset;
370 unsigned long black_color = GetColor ("black"); 387 unsigned long black_color = GetColor ("black");
371 388
372 miny -= win_y + font_height; 389 miny -= win_y + font_height;
373 maxy -= win_y - font_height; 390 maxy -= win_y - font_height;
374 391
376 XClearArea (disp, root, win_x, win_y, width, height, False); 393 XClearArea (disp, root, win_x, win_y, width, height, False);
377 394
378 for (lin = listlen; lin--;) 395 for (lin = listlen; lin--;)
379 { 396 {
380 struct linematrix *line = lines + (opt_reverse ? listlen - lin - 1 : lin); 397 struct linematrix *line = lines + (opt_reverse ? listlen - lin - 1 : lin);
398 struct displaymatrix *display_line = display + lin;
381 399
382 offset -= font_height; 400 offset -= font_height;
383 401
384 if (offset < miny || offset > maxy) 402 if (offset < miny || offset > maxy)
385 continue; 403 continue;
386 404
405 /* if this line is a different than it was, then it
406 * needs displaying */
387 if (clear && opt_noflicker) 407 if (!opt_noflicker
388 XClearArea (disp, root, win_x, win_y + offset - font_height, 408 || refresh_all
389 width + effect_x_space, font_height + effect_y_space, False); 409 || display_line->len != line->len
390 410 || display_line->color != line->color
391 if (opt_outline) 411 || memcmp (display_line->line, line->line, line->len))
392 { 412 {
393 int x, y; 413 /* don't bother updating the record of what has been
414 * displayed if -noflicker isn't in effect, since we redraw
415 * the whole display every time anyway */
416 if (opt_noflicker)
417 {
418 /* update the record of what has been displayed;
419 * first make sure the buffer is big enough */
420 if (display_line->buffer_size < line->len)
421 {
422 display_line->buffer_size = line->len;
423 display_line->line = xrealloc (display_line->line, display_line->buffer_size);
424 }
425
426 display_line->len = line->len;
427 display_line->color = line->color;
428 memcpy (display_line->line, line->line, line->len);
429
430 if (clear)
431 XClearArea (disp, root, win_x, win_y + offset - font_ascent,
432 width + effect_x_space, font_height + effect_y_space, False);
433 }
434
435 if (opt_outline)
436 {
437 int x, y;
394 XSetForeground (disp, WinGC, black_color); 438 XSetForeground (disp, WinGC, black_color);
395 439
396 for (x = -1; x < 2; x += 2) 440 for (x = -1; x <= 1; x += 2)
397 for (y = -1; y < 2; y += 2) 441 for (y = -1; y <= 1; y += 2)
398 XmbDrawString (disp, root, fontset, WinGC, 442 XmbDrawString (disp, root, fontset, WinGC,
399 win_x + effect_x_offset + x, 443 win_x + effect_x_offset + x,
400 win_y + effect_y_offset + y + offset - font_height + font_ascent, 444 win_y + y + offset,
401 line->line, line->len); 445 line->line, line->len);
402 } 446 }
403 else if (opt_shade) 447 else if (opt_shade)
404 { 448 {
405 XSetForeground (disp, WinGC, black_color); 449 XSetForeground (disp, WinGC, black_color);
450 XmbDrawString (disp, root, fontset, WinGC,
451 win_x + effect_x_offset + SHADE_X,
452 win_y + offset + SHADE_Y,
453 line->line, line->len);
454 }
455
456 XSetForeground (disp, WinGC, line->color);
406 XmbDrawString (disp, root, fontset, WinGC, 457 XmbDrawString (disp, root, fontset, WinGC,
407 win_x + effect_x_offset + SHADE_X, 458 win_x + effect_x_offset,
408 win_y + effect_y_offset + offset + SHADE_Y - font_height + font_ascent, 459 win_y + offset,
409 line->line, line->len);
410 }
411
412 XSetForeground (disp, WinGC, line->color);
413 XmbDrawString (disp, root, fontset, WinGC,
414 win_x + effect_x_offset,
415 win_y + effect_y_offset + offset - font_height + font_ascent,
416 line->line, line->len); 460 line->line, line->len);
461 }
417 } 462 }
418 463
419 if (opt_frame) 464 if (opt_frame)
420 { 465 {
421 XSetForeground (disp, WinGC, GetColor (def_color)); 466 XSetForeground (disp, WinGC, GetColor (def_color));
446 if (i == 0) 491 if (i == 0)
447 { /* matched */ 492 { /* matched */
448 int match_start = matched[0].rm_so; 493 int match_start = matched[0].rm_so;
449 int match_end = matched[0].rm_eo; 494 int match_end = matched[0].rm_eo;
450 int old_len = match_end - match_start; 495 int old_len = match_end - match_start;
451 int new_len = strlen(transform_to); 496 int new_len = strlen (transform_to);
452 int old_whole_len = strlen(s); 497 int old_whole_len = strlen (s);
498
453 printf("regexp was matched by '%s' - replace with '%s'\n", s, transform_to); 499 printf ("regexp was matched by '%s' - replace with '%s'\n", s, transform_to);
454 printf("match is from %d to %d\n", 500 printf ("match is from %d to %d\n", match_start, match_end);
455 match_start, match_end);
456 if (new_len > old_len) { 501 if (new_len > old_len)
457 s = realloc(s, old_whole_len + new_len - old_len); 502 s = xrealloc(s, old_whole_len + new_len - old_len);
458 } 503
459 if (new_len != old_len) { 504 if (new_len != old_len)
505 {
460 memcpy(s + match_end + new_len - old_len, 506 memcpy(s + match_end + new_len - old_len,
461 s + match_end, 507 s + match_end,
462 old_whole_len - match_end); 508 old_whole_len - match_end);
463 s[old_whole_len + new_len - old_len] = '\0'; 509 s[old_whole_len + new_len - old_len] = '\0';
464 } 510 }
511
465 memcpy(s + match_start, 512 memcpy (s + match_start,
466 transform_to, 513 transform_to,
467 new_len); 514 new_len);
468 printf("transformed to '%s'\n", s); 515 printf ("transformed to '%s'\n", s);
469 } 516 }
470 else 517 else
471 { 518 {
472 printf("regexp was not matched by '%s'\n", s); 519 printf ("regexp was not matched by '%s'\n", s);
473 } 520 }
474 } 521 }
475} 522}
476#endif 523#endif
477 524
488 535
489 return r; 536 return r;
490} 537}
491 538
492/* 539/*
493 * This routine should read a single line, no matter how long. 540 * This routine can read a line of any length if it is called enough times.
494 */ 541 */
495int 542int
496lineinput (struct logfile_entry *logfile) 543lineinput (struct logfile_entry *logfile)
497{ 544{
498 char buff[1024], *p = buff; 545 char buff[1024], *p;
499 int ch; 546 int ch;
500 /* HACK this - to add on the length of any partial line which we will be appending to */ 547 /* HACK-2: add on the length of any partial line which we will be appending to */
501 int ofs = logfile->buf ? strlen (logfile->buf) : 0; 548 int ofs = logfile->buf ? strlen (logfile->buf) : 0;
502 549
550 /* this loop ensures that the whole line is read, even if it's
551 * longer than the buffer. we need to do this because when --whole
552 * is in effect we don't know whether to display the line or not
553 * until we've seen how (ie. whether) it ends */
503 do 554 do
504 { 555 {
556 p = buff;
557 do
558 {
505 ch = fgetc (logfile->fp); 559 ch = fgetc (logfile->fp);
506 560
507 if (ch == '\n' || ch == EOF) 561 if (ch == '\n' || ch == EOF)
508 break; 562 break;
509 else if (ch == '\r') 563 else if (ch == '\r')
510 continue; /* skip */ 564 continue; /* skip */
511 else if (ch == '\t') 565 else if (ch == '\t')
512 { 566 {
513 do 567 do
514 { 568 {
515 *p++ = ' '; 569 *p++ = ' ';
516 ofs++; 570 ofs++;
517 } 571 }
518 while (ofs & 7); 572 while (ofs & 7);
519 }
520 else
521 {
522 *p++ = ch;
523 ofs++;
524 }
525 } 573 }
574 else
575 {
576 *p++ = ch;
577 ofs++;
578 }
579 }
526 while (p < buff + (sizeof buff) - 8 - 1); 580 while (p < buff + (sizeof buff) - 8 - 1);
527 581
528 if (p == buff && ch == EOF) 582 if (p == buff && ch == EOF)
529 return 0; 583 return 0;
530 584
531 *p = 0; 585 *p = 0;
532 586
533 p = concat_line (logfile->buf, buff); 587 p = concat_line (logfile->buf, buff);
534 free (logfile->buf); logfile->buf = p; 588 free (logfile->buf); logfile->buf = p;
589 }
590 while (ch != '\n' && ch != EOF);
535 591
536 logfile->lastpartial = logfile->partial; 592 logfile->lastpartial = logfile->partial;
537 /* there are 3 ways we could have exited the loop: reading '\n', 593 /* there are 3 ways we could have exited the loop: reading '\n',
538 * reaching EOF, or filling the buffer; the 2nd and 3rd of these 594 * reaching EOF, or filling the buffer; the 2nd and 3rd of these
539 * both result in a partial line */ 595 * both result in a partial line */
618 sleep (1); 674 sleep (1);
619 if (e->fp) 675 if (e->fp)
620 fclose (e->fp); 676 fclose (e->fp);
621 if (openlog (e) == NULL) 677 if (openlog (e) == NULL)
622 continue; 678 continue;
679 if (fstat (fileno (e->fp), &stats) < 0)
680 continue;
623 } 681 }
624 682
625 /* HACK this - stats can be uninitialised here (if the file
626 * didn't exist when stat() was called, but was recreated during
627 * the sleep(1)) */
628 if (stats.st_ino != e->inode) 683 if (stats.st_ino != e->inode)
629 { /* file renamed? */ 684 { /* file renamed? */
630 if (e->fp) 685 if (e->fp)
631 fclose (e->fp); 686 fclose (e->fp);
632 if (openlog (e) == NULL) 687 if (openlog (e) == NULL)
688 continue;
689 if (fstat (fileno (e->fp), &stats) < 0)
633 continue; 690 continue;
634 } 691 }
635 692
636 if (stats.st_size < e->last_size) 693 if (stats.st_size < e->last_size)
637 { /* file truncated? */ 694 { /* file truncated? */
673 struct logfile_entry *current; 730 struct logfile_entry *current;
674 731
675 for (cur_line = idx; cur_line > 0; cur_line--) 732 for (cur_line = idx; cur_line > 0; cur_line--)
676 lines[cur_line] = lines[cur_line - 1]; 733 lines[cur_line] = lines[cur_line - 1];
677 734
678 lines[0].line = strdup ("~"); 735 lines[0].line = xstrdup ("~");
679 736
680 for (current = loglist; current; current = current->next) 737 for (current = loglist; current; current = current->next)
681 if (current->index >= 0 && current->index <= idx) 738 if (current->index >= 0 && current->index <= idx)
682 current->index++; 739 current->index++;
683} 740}
689 */ 746 */
690static void 747static void
691split_line (int idx, const char *str, unsigned long color) 748split_line (int idx, const char *str, unsigned long color)
692{ 749{
693 int l = strlen (str); 750 int l = strlen (str);
751 int last_wrapped = 0;
694 const char *p = str; 752 const char *p = str;
753 static int continuation_width = -1;
754 static int continuation_length;
755
756 /* only calculate the continuation's width once */
757 if (continuation_width == -1)
758 {
759 continuation_length = strlen (continuation);
760 continuation_width = XmbTextEscapement (fontset, continuation, continuation_length);
761 }
695 762
696 do 763 do
697 { 764 {
698 const char *beg = p; 765 const char *beg = p;
766 int w = last_wrapped ? continuation_width : 0;
699 int w = 0, wrapped = 0; 767 int wrapped = 0;
700 const char *break_p = NULL; 768 const char *break_p = NULL;
701 769
702 while (*p) 770 while (*p)
703 { 771 {
772 int cw, len;
773
704 /* find the length in bytes of the next multibyte character */ 774 /* find the length in bytes of the next multibyte character */
705 int len = mblen (p, l); 775 len = mblen (p, l);
706 if (len <= 0) 776 if (len <= 0)
707 len = 1; /* ignore (don't skip) illegal character sequences */ 777 len = 1; /* ignore (don't skip) illegal character sequences */
708 778
709 /* find the width in pixels of the next character */ 779 /* find the width in pixels of the next character */
710 int cw = XmbTextEscapement (fontset, p, len); 780 cw = XmbTextEscapement (fontset, p, len);
711 if (cw + w > width - effect_x_space) 781 if (cw + w > width - effect_x_space)
712 { 782 {
783 if (p == beg)
784 {
785 fprintf (stderr, "we can't even fit a single character onto the line\n");
786 if (len == 1) fprintf (stderr, "(the character we couldn't fit was '%c')\n", *p);
787 exit (1);
788 }
789
713 wrapped = 1; 790 wrapped = 1;
714 break; 791 break;
715 } 792 }
716 793
717 if (opt_wordwrap && len == 1 && p[0] == ' ') 794 if (opt_wordwrap && len == 1 && p[0] == ' ')
730 l += p - break_p; 807 l += p - break_p;
731 p = break_p; 808 p = break_p;
732 } 809 }
733 810
734 { 811 {
812 int len = p - beg + (last_wrapped ? continuation_length : 0);
735 char *s = xmalloc (p - beg + 1); 813 char *s = xmalloc (len + 1);
736 memcpy (s, beg, p - beg); 814 if (last_wrapped)
815 {
816 memcpy (s, continuation, continuation_length);
817 memcpy (s + continuation_length, beg, p - beg);
818 }
819 else
820 memcpy (s, beg, len);
821
737 s[p - beg] = 0; 822 s[len] = 0;
738 insert_line (idx); 823 insert_line (idx);
739 lines[idx].line = s; 824 lines[idx].line = s;
740 lines[idx].len = p - beg; 825 lines[idx].len = len;
741 lines[idx].color = color; 826 lines[idx].color = color;
742 } 827 }
743 828
744 /* if we wrapped at a space, don't display the space */ 829 /* if we wrapped at a space, don't display the space */
745 if (opt_wordwrap && wrapped && break_p && break_p != beg) 830 if (opt_wordwrap && wrapped && break_p && break_p != beg)
746 { 831 {
747 l--; 832 l--;
748 p++; 833 p++;
749 } 834 }
835
836 last_wrapped = wrapped;
750 } 837 }
751 while (l); 838 while (l);
752} 839}
753 840
754/* 841/*
770} 857}
771 858
772static void 859static void
773main_loop (void) 860main_loop (void)
774{ 861{
775 lines = xmalloc (sizeof (struct linematrix) * listlen);
776 int lin; 862 int lin;
777 time_t lastreload; 863 time_t lastreload;
778 Region region = XCreateRegion (); 864 Region region = XCreateRegion ();
779 XEvent xev; 865 XEvent xev;
780 struct logfile_entry *lastprinted = NULL; 866 struct logfile_entry *lastprinted = NULL;
781 struct logfile_entry *current; 867 struct logfile_entry *current;
782 int need_update = 1; 868 int need_update = 1;
783 869
870 lines = xmalloc (sizeof (struct linematrix) * listlen);
871 display = xmalloc (sizeof (struct displaymatrix) * listlen);
872
784 lastreload = time (NULL); 873 lastreload = time (NULL);
785 874
786 /* Initialize linematrix */ 875 /* Initialize linematrix */
787 for (lin = 0; lin < listlen; lin++) 876 for (lin = 0; lin < listlen; lin++)
788 { 877 {
789 lines[lin].line = strdup ("~"); 878 lines[lin].line = xstrdup ("~");
790 lines[lin].len = 1; 879 lines[lin].len = 1;
880 display[lin].line = xstrdup("");
881 display[lin].len = 0;
882 display[lin].buffer_size = 0;
791 lines[lin].color = GetColor (def_color); 883 lines[lin].color = GetColor (def_color);
792 } 884 }
793 885
794 for (;;) 886 for (;;)
795 { 887 {
820 912
821 /* print filename if any, and if last line was from 913 /* print filename if any, and if last line was from
822 * different file */ 914 * different file */
823 if (!opt_nofilename && lastprinted != current && current->desc[0]) 915 if (!opt_nofilename && lastprinted != current && current->desc[0])
824 { 916 {
825 char buf[1024]; /* HACK */
826 snprintf (buf, sizeof (buf), "[%s]", current->desc);
827 split_line (listlen - 1, buf, current->color); 917 split_line (listlen - 1, "[", current->color);
918 append_line (listlen - 1, current->desc);
919 append_line (listlen - 1, "]");
828 } 920 }
829 921
830 /* if this is the same file we showed last, and the 922 /* if we're dealing with partial lines, and the last
831 * last time we showed it, it wasn't finished, then 923 * time we showed the line it wasn't finished ... */
832 * append to the last line shown */
833 if (lastprinted == current && current->lastpartial)
834 append_line (listlen - 1, current->buf);
835 else if (current->lastpartial) 924 if (!opt_whole && current->lastpartial)
836 { 925 {
926 /* if this is the same file we showed last then
927 append to the last line shown */
928 if (lastprinted == current)
929 append_line (listlen - 1, current->buf);
930 else
931 {
932 /* but if a different file has been shown in the
933 * mean time, make a new line, starting with the
934 * continuation string */
837 split_line (listlen - 1, continuation, current->color); 935 split_line (listlen - 1, continuation, current->color);
838 append_line (listlen - 1, current->buf); 936 append_line (listlen - 1, current->buf);
937 }
839 } 938 }
840 else 939 else
940 /* otherwise just make a plain and simple new line */
841 split_line (listlen - 1, current->buf, current->color); 941 split_line (listlen - 1, current->buf, current->color);
842 942
843 free (current->buf), current->buf = 0; 943 free (current->buf), current->buf = 0;
844 current->index = listlen - 1; 944 current->index = listlen - 1;
845 lastprinted = current; 945 lastprinted = current;
846 } 946 }
847 } 947 }
848 948
849 if (need_update) 949 if (need_update)
850 { 950 {
851 redraw (); 951 redraw (0);
852 need_update = 0; 952 need_update = 0;
853 } 953 }
854 else 954 else
855 { 955 {
856 XFlush (disp); 956 XFlush (disp);
913 XRectangle r; 1013 XRectangle r;
914 1014
915 XSetRegion (disp, WinGC, region); 1015 XSetRegion (disp, WinGC, region);
916 XClipBox (region, &r); 1016 XClipBox (region, &r);
917 1017
918 refresh (r.y, r.y + r.height, 0); 1018 refresh (r.y, r.y + r.height, 0, 1);
919 1019
920 XDestroyRegion (region); 1020 XDestroyRegion (region);
921 region = XCreateRegion (); 1021 region = XCreateRegion ();
922 } 1022 }
923 } 1023 }
1050 { 1150 {
1051 if ((e->fp = fdopen (0, "r")) == NULL) 1151 if ((e->fp = fdopen (0, "r")) == NULL)
1052 perror ("fdopen"), exit (1); 1152 perror ("fdopen"), exit (1);
1053 if (fcntl (0, F_SETFL, O_NONBLOCK) < 0) 1153 if (fcntl (0, F_SETFL, O_NONBLOCK) < 0)
1054 perror ("fcntl"), exit (1); 1154 perror ("fcntl"), exit (1);
1155
1055 e->fname = NULL; 1156 e->fname = NULL;
1056 e->inode = 0; 1157 e->inode = 0;
1057 e->desc = xstrdup ("stdin"); 1158 e->desc = xstrdup ("stdin");
1058 } 1159 }
1059 else 1160 else
1060 { 1161 {
1061 int l;
1062
1063 e->fname = xstrdup (fname); 1162 e->fname = xstrdup (fname);
1163
1064 if (openlog (e) == NULL) 1164 if (openlog (e) == NULL)
1065 perror (fname), exit (1); 1165 perror (fname), exit (1);
1066 1166
1067 l = strlen (desc); 1167 e->desc = xstrdup (desc);
1068 /* HACK on this - width is in pixels now */
1069 if (l > width - 2) /* must account for [ ] */
1070 l = width - 2;
1071 e->desc = xmalloc (l + 1);
1072 memcpy (e->desc, desc, l);
1073 *(e->desc + l) = '\0';
1074 } 1168 }
1075 1169
1076 e->color = GetColor (fcolor); 1170 e->color = GetColor (fcolor);
1077 e->partial = 0; 1171 e->partial = 0;
1078 e->next = NULL; 1172 e->next = NULL;
1079 1173
1080 if (!loglist) 1174 if (!loglist)
1081 loglist = e; 1175 loglist = e;
1082 if (loglist_tail) 1176 if (loglist_tail)
1083 loglist_tail->next = e; 1177 loglist_tail->next = e;
1178
1084 loglist_tail = e; 1179 loglist_tail = e;
1085 } 1180 }
1086 } 1181 }
1087 1182
1088 if (!loglist) 1183 if (!loglist)
1090 fprintf (stderr, "You did not specify any files to tail\n" 1185 fprintf (stderr, "You did not specify any files to tail\n"
1091 "use %s --help for help\n", argv[0]); 1186 "use %s --help for help\n", argv[0]);
1092 exit (1); 1187 exit (1);
1093 } 1188 }
1094 1189
1190 if (opt_update && opt_whole)
1191 {
1192 fprintf (stderr, "Specify at most one of -update and -whole\n");
1193 exit (1);
1194 }
1095 if (opt_partial && opt_whole) 1195 else if (opt_partial && opt_whole)
1096 { 1196 {
1097 fprintf (stderr, "Specify at most one of -partial and -whole\n"); 1197 fprintf (stderr, "Specify at most one of -partial and -whole\n");
1098 exit (1); 1198 exit (1);
1099 } 1199 }
1100 1200
1101 /* HACK this - do we want to allow both -shade and -outline? */ 1201 /* HACK-7: do we want to allow both -shade and -outline? */
1102 if (opt_shade && opt_outline) 1202 if (opt_shade && opt_outline)
1103 { 1203 {
1104 fprintf (stderr, "Specify at most one of -shade and -outline\n"); 1204 fprintf (stderr, "Specify at most one of -shade and -outline\n");
1105 exit (1); 1205 exit (1);
1106 } 1206 }
1107 1207
1108 if (opt_partial) 1208 if (opt_partial)
1109 /* if we specifically requested to see partial lines then don't insist on whole lines */ 1209 /* if we specifically requested to see partial lines then don't insist on whole lines */
1110 opt_whole = 0; 1210 opt_whole = 0;
1111 else if (file_count > 1) 1211 else if (file_count > 1)
1112 /* otherwise, if we've viewing multiple files, default to showing whole lines */ 1212 /* otherwise, if we're viewing multiple files, default to showing whole lines */
1113 opt_whole = 1; 1213 opt_whole = 1;
1114 1214
1115#if HAS_REGEX 1215#if HAS_REGEX
1116 if (transform) 1216 if (transform)
1117 { 1217 {
1169{ 1269{
1170 void *p; 1270 void *p;
1171 1271
1172 while ((p = strdup (string)) == NULL) 1272 while ((p = strdup (string)) == NULL)
1173 { 1273 {
1174 fprintf (stderr, "Memory exausted."); 1274 fprintf (stderr, "Memory exhausted in xstrdup().\n");
1175 sleep (10); 1275 sleep (10);
1176 } 1276 }
1177 1277
1178 return p; 1278 return p;
1179} 1279}
1183{ 1283{
1184 void *p; 1284 void *p;
1185 1285
1186 while ((p = malloc (size)) == NULL) 1286 while ((p = malloc (size)) == NULL)
1187 { 1287 {
1188 fprintf (stderr, "Memory exausted."); 1288 fprintf (stderr, "Memory exhausted in xmalloc().\n");
1289 sleep (10);
1290 }
1291
1292 return p;
1293}
1294
1295void *
1296xrealloc (void *ptr, size_t size)
1297{
1298 void *p;
1299
1300 while ((p = realloc (ptr, size)) == NULL)
1301 {
1302 fprintf (stderr, "Memory exhausted in xrealloc().\n");
1189 sleep (10); 1303 sleep (10);
1190 } 1304 }
1191 1305
1192 return p; 1306 return p;
1193} 1307}
1215 " startup\n" 1329 " startup\n"
1216 " -i | -interval seconds interval between checks (fractional\n" 1330 " -i | -interval seconds interval between checks (fractional\n"
1217 " values o.k.). Default 2.4 seconds\n" 1331 " values o.k.). Default 2.4 seconds\n"
1218 " -V display version information and exit\n" 1332 " -V display version information and exit\n"
1219 "\n"); 1333 "\n");
1220 printf ("Example:\n%s -g 80x25+100+50 -font fixed /var/log/messages,green " 1334 printf ("Example:\n%s -g 800x250+100+50 -font fixed /var/log/messages,green "
1221 "/var/log/secure,red,'ALERT'\n", myname); 1335 "/var/log/secure,red,'ALERT'\n", myname);
1222 exit (0); 1336 exit (0);
1223} 1337}
1224 1338
1225void 1339void
1239 case -1: 1353 case -1:
1240 return -1; 1354 return -1;
1241 case 0: 1355 case 0:
1242 break; 1356 break;
1243 default: 1357 default:
1244 printf("%d\n", pid); 1358 /*printf("%d\n", pid);*/
1245 exit (0); 1359 exit (0);
1246 } 1360 }
1247 1361
1248 if (setsid () == -1) 1362 if (setsid () == -1)
1249 return -1; 1363 return -1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines