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.28 by chris_moore, Mon Mar 29 17:25:51 2004 UTC vs.
Revision 1.43 by chris_moore, Wed Mar 31 17:07:02 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.
72struct displaymatrix 75struct displaymatrix
73{ 76{
74 char *line; 77 char *line;
75 int len; 78 int len;
76 int buffer_size; 79 int buffer_size;
80 unsigned long color;
77}; 81};
78 82
79/* global variables */ 83/* global variables */
80struct linematrix *lines; 84struct linematrix *lines;
81struct displaymatrix *display; 85struct displaymatrix *display;
377/* Just redraw everything without clearing (i.e. after an EXPOSE event) */ 381/* Just redraw everything without clearing (i.e. after an EXPOSE event) */
378void 382void
379refresh (int miny, int maxy, int clear, int refresh_all) 383refresh (int miny, int maxy, int clear, int refresh_all)
380{ 384{
381 int lin; 385 int lin;
382 int offset = (listlen + 1) * font_height; 386 int offset = listlen * font_height + font_ascent + effect_y_offset;
383 unsigned long black_color = GetColor ("black"); 387 unsigned long black_color = GetColor ("black");
384 388
385 miny -= win_y + font_height; 389 miny -= win_y + font_height;
386 maxy -= win_y - font_height; 390 maxy -= win_y - font_height;
387 391
396 offset -= font_height; 400 offset -= font_height;
397 401
398 if (offset < miny || offset > maxy) 402 if (offset < miny || offset > maxy)
399 continue; 403 continue;
400 404
405 /* if this line is a different than it was, then it
406 * needs displaying */
401 if (opt_noflicker) 407 if (!opt_noflicker
402 { 408 || refresh_all
403 /* if this line is a different than it was, then it 409 || display_line->len != line->len
404 * needs displaying */ 410 || display_line->color != line->color
405 if (refresh_all || 411 || memcmp (display_line->line, line->line, line->len))
406 display_line->len != line->len || 412 {
407 strcmp(display_line->line, line->line)) 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)
408 { 417 {
409 /* update the record of what has been displayed; 418 /* update the record of what has been displayed;
410 * first make sure the buffer is big enough */ 419 * first make sure the buffer is big enough */
411 if (display_line->buffer_size <= line->len) 420 if (display_line->buffer_size <= line->len)
412 { 421 {
413 display_line->buffer_size = line->len + 1; 422 display_line->buffer_size = line->len;
414 display_line->line = xrealloc(display_line->line, display_line->buffer_size); 423 display_line->line = xrealloc (display_line->line, display_line->buffer_size);
415 } 424 }
416 strcpy(display_line->line, line->line); 425
417 display_line->len = line->len; 426 display_line->len = line->len;
427 display_line->color = line->color;
428 memcpy (display_line->line, line->line, line->len);
418 429
419 if (clear) 430 if (clear)
420 XClearArea (disp, root, win_x, win_y + offset - font_height, 431 XClearArea (disp, root, win_x, win_y + offset - font_ascent,
421 width + effect_x_space, font_height + effect_y_space, False); 432 width + effect_x_space, font_height + effect_y_space, False);
422
423 if (opt_outline)
424 {
425 int x, y;
426 XSetForeground (disp, WinGC, black_color);
427
428 for (x = -1; x < 2; x += 2)
429 for (y = -1; y < 2; y += 2)
430 XmbDrawString (disp, root, fontset, WinGC,
431 win_x + effect_x_offset + x,
432 win_y + effect_y_offset + y + offset - font_height + font_ascent,
433 line->line, line->len);
434 }
435 else if (opt_shade)
436 {
437 XSetForeground (disp, WinGC, black_color);
438 XmbDrawString (disp, root, fontset, WinGC,
439 win_x + effect_x_offset + SHADE_X,
440 win_y + effect_y_offset + offset + SHADE_Y - font_height + font_ascent,
441 line->line, line->len);
442 }
443
444 XSetForeground (disp, WinGC, line->color);
445 XmbDrawString (disp, root, fontset, WinGC,
446 win_x + effect_x_offset,
447 win_y + effect_y_offset + offset - font_height + font_ascent,
448 line->line, line->len);
449 } 433 }
450 } 434
451 else 435 if (opt_outline)
452 { 436 {
437 int x, y;
438 XSetForeground (disp, WinGC, black_color);
439
440 for (x = -1; x <= 1; x += 2)
441 for (y = -1; y <= 1; y += 2)
442 XmbDrawString (disp, root, fontset, WinGC,
443 win_x + effect_x_offset + x,
444 win_y + y + offset,
445 line->line, line->len);
446 }
447 else if (opt_shade)
448 {
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
453 XSetForeground (disp, WinGC, line->color); 456 XSetForeground (disp, WinGC, line->color);
454 XmbDrawString (disp, root, fontset, WinGC, 457 XmbDrawString (disp, root, fontset, WinGC,
455 win_x + effect_x_offset, 458 win_x + effect_x_offset,
456 win_y + effect_y_offset + offset - font_height + font_ascent, 459 win_y + offset,
457 line->line, line->len); 460 line->line, line->len);
458 } 461 }
459 } 462 }
460 463
461 if (opt_frame) 464 if (opt_frame)
462 { 465 {
488 if (i == 0) 491 if (i == 0)
489 { /* matched */ 492 { /* matched */
490 int match_start = matched[0].rm_so; 493 int match_start = matched[0].rm_so;
491 int match_end = matched[0].rm_eo; 494 int match_end = matched[0].rm_eo;
492 int old_len = match_end - match_start; 495 int old_len = match_end - match_start;
493 int new_len = strlen(transform_to); 496 int new_len = strlen (transform_to);
494 int old_whole_len = strlen(s); 497 int old_whole_len = strlen (s);
498
495 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);
496 printf("match is from %d to %d\n", 500 printf ("match is from %d to %d\n", match_start, match_end);
497 match_start, match_end);
498 if (new_len > old_len) { 501 if (new_len > old_len)
499 s = xrealloc(s, old_whole_len + new_len - old_len); 502 s = xrealloc(s, old_whole_len + new_len - old_len);
500 } 503
501 if (new_len != old_len) { 504 if (new_len != old_len)
505 {
502 memcpy(s + match_end + new_len - old_len, 506 memcpy(s + match_end + new_len - old_len,
503 s + match_end, 507 s + match_end,
504 old_whole_len - match_end); 508 old_whole_len - match_end);
505 s[old_whole_len + new_len - old_len] = '\0'; 509 s[old_whole_len + new_len - old_len] = '\0';
506 } 510 }
511
507 memcpy(s + match_start, 512 memcpy (s + match_start,
508 transform_to, 513 transform_to,
509 new_len); 514 new_len);
510 printf("transformed to '%s'\n", s); 515 printf ("transformed to '%s'\n", s);
511 } 516 }
512 else 517 else
513 { 518 {
514 printf("regexp was not matched by '%s'\n", s); 519 printf ("regexp was not matched by '%s'\n", s);
515 } 520 }
516 } 521 }
517} 522}
518#endif 523#endif
519 524
530 535
531 return r; 536 return r;
532} 537}
533 538
534/* 539/*
535 * 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.
536 */ 541 */
537int 542int
538lineinput (struct logfile_entry *logfile) 543lineinput (struct logfile_entry *logfile)
539{ 544{
540 char buff[1024], *p = buff; 545 char buff[1024], *p = buff;
541 int ch; 546 int ch;
542 /* 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 */
543 int ofs = logfile->buf ? strlen (logfile->buf) : 0; 548 int ofs = logfile->buf ? strlen (logfile->buf) : 0;
544 549
545 do 550 do
546 { 551 {
547 ch = fgetc (logfile->fp); 552 ch = fgetc (logfile->fp);
660 sleep (1); 665 sleep (1);
661 if (e->fp) 666 if (e->fp)
662 fclose (e->fp); 667 fclose (e->fp);
663 if (openlog (e) == NULL) 668 if (openlog (e) == NULL)
664 continue; 669 continue;
670 if (fstat (fileno (e->fp), &stats) < 0)
671 continue;
665 } 672 }
666 673
667 /* HACK this - stats can be uninitialised here (if the file
668 * didn't exist when stat() was called, but was recreated during
669 * the sleep(1)) */
670 if (stats.st_ino != e->inode) 674 if (stats.st_ino != e->inode)
671 { /* file renamed? */ 675 { /* file renamed? */
672 if (e->fp) 676 if (e->fp)
673 fclose (e->fp); 677 fclose (e->fp);
674 if (openlog (e) == NULL) 678 if (openlog (e) == NULL)
679 continue;
680 if (fstat (fileno (e->fp), &stats) < 0)
675 continue; 681 continue;
676 } 682 }
677 683
678 if (stats.st_size < e->last_size) 684 if (stats.st_size < e->last_size)
679 { /* file truncated? */ 685 { /* file truncated? */
731 */ 737 */
732static void 738static void
733split_line (int idx, const char *str, unsigned long color) 739split_line (int idx, const char *str, unsigned long color)
734{ 740{
735 int l = strlen (str); 741 int l = strlen (str);
742 int last_wrapped = 0;
736 const char *p = str; 743 const char *p = str;
744 static int continuation_width = -1;
745 static int continuation_length;
746
747 /* only calculate the continuation's width once */
748 if (continuation_width == -1)
749 {
750 continuation_length = strlen (continuation);
751 continuation_width = XmbTextEscapement (fontset, continuation, continuation_length);
752 }
737 753
738 do 754 do
739 { 755 {
740 const char *beg = p; 756 const char *beg = p;
757 int w = last_wrapped ? continuation_width : 0;
741 int w = 0, wrapped = 0; 758 int wrapped = 0;
742 const char *break_p = NULL; 759 const char *break_p = NULL;
743 760
744 while (*p) 761 while (*p)
745 { 762 {
746 /* find the length in bytes of the next multibyte character */ 763 /* find the length in bytes of the next multibyte character */
750 767
751 /* find the width in pixels of the next character */ 768 /* find the width in pixels of the next character */
752 int cw = XmbTextEscapement (fontset, p, len); 769 int cw = XmbTextEscapement (fontset, p, len);
753 if (cw + w > width - effect_x_space) 770 if (cw + w > width - effect_x_space)
754 { 771 {
772 if (p == beg)
773 {
774 fprintf (stderr, "we can't even fit a single character onto the line\n");
775 if (len == 1) fprintf (stderr, "(the character we couldn't fit was '%c')\n", *p);
776 exit (1);
777 }
778
755 wrapped = 1; 779 wrapped = 1;
756 break; 780 break;
757 } 781 }
758 782
759 if (opt_wordwrap && len == 1 && p[0] == ' ') 783 if (opt_wordwrap && len == 1 && p[0] == ' ')
772 l += p - break_p; 796 l += p - break_p;
773 p = break_p; 797 p = break_p;
774 } 798 }
775 799
776 { 800 {
801 int len = p - beg + (last_wrapped ? continuation_length : 0);
777 char *s = xmalloc (p - beg + 1); 802 char *s = xmalloc (len + 1);
778 memcpy (s, beg, p - beg); 803 if (last_wrapped)
804 {
805 memcpy (s, continuation, continuation_length);
806 memcpy (s + continuation_length, beg, p - beg);
807 }
808 else
809 memcpy (s, beg, len);
810
779 s[p - beg] = 0; 811 s[len] = 0;
780 insert_line (idx); 812 insert_line (idx);
781 lines[idx].line = s; 813 lines[idx].line = s;
782 lines[idx].len = p - beg; 814 lines[idx].len = len;
783 lines[idx].color = color; 815 lines[idx].color = color;
784 } 816 }
785 817
786 /* if we wrapped at a space, don't display the space */ 818 /* if we wrapped at a space, don't display the space */
787 if (opt_wordwrap && wrapped && break_p && break_p != beg) 819 if (opt_wordwrap && wrapped && break_p && break_p != beg)
788 { 820 {
789 l--; 821 l--;
790 p++; 822 p++;
791 } 823 }
824
825 last_wrapped = wrapped;
792 } 826 }
793 while (l); 827 while (l);
794} 828}
795 829
796/* 830/*
831 { 865 {
832 lines[lin].line = xstrdup ("~"); 866 lines[lin].line = xstrdup ("~");
833 lines[lin].len = 1; 867 lines[lin].len = 1;
834 display[lin].line = xstrdup(""); 868 display[lin].line = xstrdup("");
835 display[lin].len = 0; 869 display[lin].len = 0;
836 display[lin].buffer_size = 1; 870 display[lin].buffer_size = 0;
837 lines[lin].color = GetColor (def_color); 871 lines[lin].color = GetColor (def_color);
838 } 872 }
839 873
840 for (;;) 874 for (;;)
841 { 875 {
866 900
867 /* print filename if any, and if last line was from 901 /* print filename if any, and if last line was from
868 * different file */ 902 * different file */
869 if (!opt_nofilename && lastprinted != current && current->desc[0]) 903 if (!opt_nofilename && lastprinted != current && current->desc[0])
870 { 904 {
871 char buf[1024]; /* HACK */
872 snprintf (buf, sizeof (buf), "[%s]", current->desc);
873 split_line (listlen - 1, buf, current->color); 905 split_line (listlen - 1, "[", current->color);
906 append_line (listlen - 1, current->desc);
907 append_line (listlen - 1, "]");
874 } 908 }
875 909
876 /* if this is the same file we showed last, and the 910 /* if we're dealing with partial lines, and the last
877 * last time we showed it, it wasn't finished, then 911 * time we showed the line it wasn't finished ... */
878 * append to the last line shown */
879 if (lastprinted == current && current->lastpartial)
880 append_line (listlen - 1, current->buf);
881 else if (current->lastpartial) 912 if (!opt_whole && current->lastpartial)
882 { 913 {
914 /* if this is the same file we showed last then
915 append to the last line shown */
916 if (lastprinted == current)
917 append_line (listlen - 1, current->buf);
918 else
919 {
920 /* but if a different file has been shown in the
921 * mean time, make a new line, starting with the
922 * continuation string */
883 split_line (listlen - 1, continuation, current->color); 923 split_line (listlen - 1, continuation, current->color);
884 append_line (listlen - 1, current->buf); 924 append_line (listlen - 1, current->buf);
925 }
885 } 926 }
886 else 927 else
928 /* otherwise just make a plain and simple new line */
887 split_line (listlen - 1, current->buf, current->color); 929 split_line (listlen - 1, current->buf, current->color);
888 930
889 free (current->buf), current->buf = 0; 931 free (current->buf), current->buf = 0;
890 current->index = listlen - 1; 932 current->index = listlen - 1;
891 lastprinted = current; 933 lastprinted = current;
1096 { 1138 {
1097 if ((e->fp = fdopen (0, "r")) == NULL) 1139 if ((e->fp = fdopen (0, "r")) == NULL)
1098 perror ("fdopen"), exit (1); 1140 perror ("fdopen"), exit (1);
1099 if (fcntl (0, F_SETFL, O_NONBLOCK) < 0) 1141 if (fcntl (0, F_SETFL, O_NONBLOCK) < 0)
1100 perror ("fcntl"), exit (1); 1142 perror ("fcntl"), exit (1);
1143
1101 e->fname = NULL; 1144 e->fname = NULL;
1102 e->inode = 0; 1145 e->inode = 0;
1103 e->desc = xstrdup ("stdin"); 1146 e->desc = xstrdup ("stdin");
1104 } 1147 }
1105 else 1148 else
1106 { 1149 {
1107 int l;
1108
1109 e->fname = xstrdup (fname); 1150 e->fname = xstrdup (fname);
1151
1110 if (openlog (e) == NULL) 1152 if (openlog (e) == NULL)
1111 perror (fname), exit (1); 1153 perror (fname), exit (1);
1112 1154
1113 l = strlen (desc); 1155 e->desc = xstrdup (desc);
1114 /* HACK on this - width is in pixels now */
1115 if (l > width - 2) /* must account for [ ] */
1116 l = width - 2;
1117 e->desc = xmalloc (l + 1);
1118 memcpy (e->desc, desc, l);
1119 *(e->desc + l) = '\0';
1120 } 1156 }
1121 1157
1122 e->color = GetColor (fcolor); 1158 e->color = GetColor (fcolor);
1123 e->partial = 0; 1159 e->partial = 0;
1124 e->next = NULL; 1160 e->next = NULL;
1125 1161
1126 if (!loglist) 1162 if (!loglist)
1127 loglist = e; 1163 loglist = e;
1128 if (loglist_tail) 1164 if (loglist_tail)
1129 loglist_tail->next = e; 1165 loglist_tail->next = e;
1166
1130 loglist_tail = e; 1167 loglist_tail = e;
1131 } 1168 }
1132 } 1169 }
1133 1170
1134 if (!loglist) 1171 if (!loglist)
1136 fprintf (stderr, "You did not specify any files to tail\n" 1173 fprintf (stderr, "You did not specify any files to tail\n"
1137 "use %s --help for help\n", argv[0]); 1174 "use %s --help for help\n", argv[0]);
1138 exit (1); 1175 exit (1);
1139 } 1176 }
1140 1177
1178 if (opt_update && opt_whole)
1179 {
1180 fprintf (stderr, "Specify at most one of -update and -whole\n");
1181 exit (1);
1182 }
1141 if (opt_partial && opt_whole) 1183 else if (opt_partial && opt_whole)
1142 { 1184 {
1143 fprintf (stderr, "Specify at most one of -partial and -whole\n"); 1185 fprintf (stderr, "Specify at most one of -partial and -whole\n");
1144 exit (1); 1186 exit (1);
1145 } 1187 }
1146 1188
1147 /* HACK this - do we want to allow both -shade and -outline? */ 1189 /* HACK-7: do we want to allow both -shade and -outline? */
1148 if (opt_shade && opt_outline) 1190 if (opt_shade && opt_outline)
1149 { 1191 {
1150 fprintf (stderr, "Specify at most one of -shade and -outline\n"); 1192 fprintf (stderr, "Specify at most one of -shade and -outline\n");
1151 exit (1); 1193 exit (1);
1152 } 1194 }
1153 1195
1154 if (opt_partial) 1196 if (opt_partial)
1155 /* if we specifically requested to see partial lines then don't insist on whole lines */ 1197 /* if we specifically requested to see partial lines then don't insist on whole lines */
1156 opt_whole = 0; 1198 opt_whole = 0;
1157 else if (file_count > 1) 1199 else if (file_count > 1)
1158 /* otherwise, if we've viewing multiple files, default to showing whole lines */ 1200 /* otherwise, if we're viewing multiple files, default to showing whole lines */
1159 opt_whole = 1; 1201 opt_whole = 1;
1160 1202
1161#if HAS_REGEX 1203#if HAS_REGEX
1162 if (transform) 1204 if (transform)
1163 { 1205 {
1299 case -1: 1341 case -1:
1300 return -1; 1342 return -1;
1301 case 0: 1343 case 0:
1302 break; 1344 break;
1303 default: 1345 default:
1304 printf("%d\n", pid); 1346 /*printf("%d\n", pid);*/
1305 exit (0); 1347 exit (0);
1306 } 1348 }
1307 1349
1308 if (setsid () == -1) 1350 if (setsid () == -1)
1309 return -1; 1351 return -1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines