Makefile.am: Fix hideous formatting.
[misc] / xtitle.c
1 #include <errno.h>
2 #include <unistd.h>
3 #include <termios.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <fcntl.h>
8
9 int main(int argc, char *argv[])
10 {
11 int query = 0;
12 int fd;
13 int openned = 0;
14 int i;
15
16 for (;;) {
17 i = getopt(argc, argv, "q");
18 if (i < 0)
19 break;
20 switch (i) {
21 case 'q':
22 query = 1;
23 break;
24 default:
25 fprintf(stderr, "usage: xtitle [-q] [STRING]\n");
26 return (1);
27 }
28 }
29
30 if (!query && optind == argc) {
31 fprintf(stderr, "xtitle: no string to set\n");
32 return (1);
33 }
34
35 {
36 char *t = getenv("TERM");
37 if (!t || strncmp(t, "xterm", 5))
38 return (0);
39 }
40
41 if (isatty(0))
42 fd = 0;
43 else {
44 fd = open("/dev/tty", O_RDWR);
45 if (fd < 0) {
46 fprintf(stderr, "xtitle: couldn't open terminal: %s", strerror(errno));
47 return (1);
48 }
49 openned = 1;
50 }
51
52 if (!query) {
53 char sp = ' ';
54 write(fd, "\33]0;", 4);
55 for (i = optind; i < argc; i++) {
56 write(fd, argv[i], strlen(argv[i]));
57 if (i < argc - 1)
58 write(fd, &sp, 1);
59 }
60 write(fd, "\7", 2);
61 } else {
62 struct termios o, n;
63 char hack;
64 int state = 0;
65
66 tcgetattr(fd, &o);
67 n = o;
68 n.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
69 |INLCR|IGNCR|ICRNL|IXON);
70 n.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
71 n.c_cflag &= ~(CSIZE|PARENB);
72 n.c_cflag |= CS8;
73 tcsetattr(fd, TCSAFLUSH, &n);
74 write(fd, "\33[21t", 5);
75
76 while (state != -1) {
77 if (read(fd, &hack, 1) < 1)
78 break;
79 switch (state) {
80 case 0:
81 if (hack == '\33') state = 1;
82 break;
83 case 1:
84 if (hack == ']') state = 2; else state = 0;
85 break;
86 case 2:
87 if (hack == 'l') state = 3; else state = 0;
88 break;
89 case 3:
90 if (hack == '\33') state = 4; else putchar(hack);
91 break;
92 case 4:
93 if (hack == '\\') { state = -1; putchar('\n'); }
94 else { putchar('\33'); putchar(hack); state = 3; }
95 break;
96 }
97 }
98
99 tcsetattr(fd, TCSAFLUSH, &o);
100 }
101
102 if (openned)
103 close(fd);
104
105 return (0);
106 }