conswdir.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Process in-band messages about window title changes.
  3. * The messages are of the form:
  4. *
  5. * \033];xxx\007
  6. *
  7. * where xxx is the new directory. This format was chosen
  8. * because it changes the label on xterm windows.
  9. */
  10. #include <u.h>
  11. #include <libc.h>
  12. char *prog = "/bin/rwd";
  13. void
  14. usage(void)
  15. {
  16. fprint(2, "usage: conswdir [/bin/rwd]\n");
  17. exits("usage");
  18. }
  19. void
  20. setpath(char *s)
  21. {
  22. switch(rfork(RFPROC|RFNOWAIT)){
  23. case 0:
  24. execl(prog, prog, s, nil);
  25. _exits(nil);
  26. }
  27. }
  28. enum
  29. {
  30. None,
  31. Esc,
  32. Brack,
  33. Semi,
  34. Bell,
  35. };
  36. int
  37. process(char *buf, int n, int *pn)
  38. {
  39. char *p;
  40. char path[4096];
  41. int start, state;
  42. start = 0;
  43. state = None;
  44. for(p=buf; p<buf+n; p++){
  45. switch(state){
  46. case None:
  47. if(*p == '\033'){
  48. start = p-buf;
  49. state++;
  50. }
  51. break;
  52. case Esc:
  53. if(*p == ']')
  54. state++;
  55. else
  56. state = None;
  57. break;
  58. case Brack:
  59. if(*p == ';')
  60. state++;
  61. else
  62. state = None;
  63. break;
  64. case Semi:
  65. if(*p == '\007')
  66. state++;
  67. else if((uchar)*p < 040)
  68. state = None;
  69. break;
  70. }
  71. if(state == Bell){
  72. memmove(path, buf+start+3, p - (buf+start+3));
  73. path[p-(buf+start+3)] = 0;
  74. p++;
  75. memmove(buf+start, p, n-(p-buf));
  76. n -= p-(buf+start);
  77. p = buf+start;
  78. p--;
  79. start = 0;
  80. state = None;
  81. setpath(path);
  82. }
  83. }
  84. /* give up if we go too long without seeing the close */
  85. *pn = n;
  86. if(state == None || p-(buf+start) >= 2048)
  87. return (p - buf);
  88. else
  89. return start;
  90. }
  91. static void
  92. catchint(void*, char *msg)
  93. {
  94. if(strstr(msg, "interrupt"))
  95. noted(NCONT);
  96. else if(strstr(msg, "kill"))
  97. noted(NDFLT);
  98. else
  99. noted(NCONT);
  100. }
  101. void
  102. main(int argc, char **argv)
  103. {
  104. char buf[4096];
  105. int n, m;
  106. notify(catchint);
  107. ARGBEGIN{
  108. default:
  109. usage();
  110. }ARGEND
  111. if(argc > 1)
  112. usage();
  113. if(argc == 1)
  114. prog = argv[0];
  115. n = 0;
  116. for(;;){
  117. m = read(0, buf+n, sizeof buf-n);
  118. if(m < 0){
  119. rerrstr(buf, sizeof buf);
  120. if(strstr(buf, "interrupt"))
  121. continue;
  122. exits(nil);
  123. }
  124. n += m;
  125. m = process(buf, n, &n);
  126. if(m > 0){
  127. write(1, buf, m);
  128. memmove(buf, buf+m, n-m);
  129. n -= m;
  130. }
  131. }
  132. }