chiark / gitweb /
debian: Fix package sections.
[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 #ifdef BASH_BUILTIN
10 #include "bash/config.h"
11 #include "bash/shell.h"
12 #include "bash/builtins.h"
13 #include "bash/builtins/common.h"
14 #include "bash/builtins/bashgetopt.h"
15 #endif
16
17 #ifdef BASH_BUILTIN
18 int xtitle_builtin(WORD_LIST *list)
19 #else
20 int main(int argc, char *argv[])
21 #endif
22 {
23   int query = 0;
24   int fd;
25   int openned = 0;
26
27 #ifdef BASH_BUILTIN
28   reset_internal_getopt();
29 #endif
30   for (;;) {
31 #ifdef BASH_BUILTIN
32     int i;
33     i = internal_getopt(list, "q");
34 #else
35     int i = getopt(argc, argv, "q");
36 #endif
37     if (i < 0)
38       break;
39     switch (i) {
40       case 'q':
41         query = 1;
42         break;
43       default:
44 #ifdef BASH_BUILTIN
45         builtin_usage();
46 #else
47         fprintf(stderr, "usage: xtitle [-q] [string]\n");
48 #endif
49         return (1);
50     }
51   }
52
53 #ifdef BASH_BUILTIN
54   if (!query && loptend == 0) {
55 #else
56   if (!query && optind == argc) {
57 #endif
58     fprintf(stderr, "xtitle: no string to set\n");
59     return (1);
60   }
61
62   {
63     char *t = getenv("TERM");
64     if (!t || strncmp(t, "xterm", 5))
65       return (0);
66   }
67
68   if (isatty(0))
69     fd = 0;
70   else {
71     fd = open("/dev/tty", O_RDWR);
72     if (fd < 0) {
73       fprintf(stderr, "xtitle: couldn't open terminal: %s", strerror(errno));
74       return (1);
75     }
76     openned = 1;
77   }
78
79   if (!query) {
80 #ifdef BASH_BUILTIN
81     WORD_LIST *l = loptend;
82     char sp = ' ';
83     write(fd, "\33]0;", 4);
84     while (l) {
85       write(fd, l->word->word, strlen(l->word->word));
86       if (l->next)
87         write(fd, &sp, 1);
88       l = l->next;
89     }
90     write(fd, "\7", 2);
91 #else
92     int i;
93     char sp = ' ';
94     write(fd, "\33]0;", 4);
95     for (i = optind; i < argc; i++) {
96       write(fd, argv[i], strlen(argv[i]));
97       if (i < argc - 1)
98         write(fd, &sp, 1);
99     }
100     write(fd, "\7", 2);
101 #endif
102   } else {
103     struct termios o, n;
104     char hack;
105     int state = 0;
106
107     tcgetattr(fd, &o);
108     n = o;
109     n.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
110                    |INLCR|IGNCR|ICRNL|IXON);
111     n.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
112     n.c_cflag &= ~(CSIZE|PARENB);
113     n.c_cflag |= CS8;
114     tcsetattr(fd, TCSAFLUSH, &n);
115     write(fd, "\33[21t", 5);
116
117     while (state != -1) {
118       if (read(fd, &hack, 1) < 1)
119         break;
120       switch (state) {
121         case 0:
122           if (hack == '\33') state = 1;
123           break;
124         case 1:
125           if (hack == ']') state = 2; else state = 0;
126           break;
127         case 2:
128           if (hack == 'l') state = 3; else state = 0;
129           break;
130         case 3:
131           if (hack == '\33') state = 4; else putchar(hack);
132           break;
133         case 4:
134           if (hack == '\\') { state = -1; putchar('\n'); }
135           else { putchar('\33'); putchar(hack); state = 3; }
136           break;
137       }
138     }
139
140     tcsetattr(fd, TCSAFLUSH, &o);
141   }
142
143   if (openned)
144     close(fd);
145
146   return (0);
147 }
148
149
150 #ifdef BASH_BUILTIN
151
152 static char *xtitle_doc[] = {
153   "Either set or read the title of the current xterm window.  With the",
154   "-q option, writes the current xterm title to standard output.  Without",
155   "the -q option, sets the xterm title to be the arguments given,",
156   "separated by space characters.  [By Mark Wooding, mdw@nsict.org]",
157   0
158 };
159
160 struct builtin xtitle_struct = {
161   "xtitle",
162   xtitle_builtin,
163   BUILTIN_ENABLED,
164   xtitle_doc,
165   "xtitle [-q] [arguments]",
166   0
167 };
168
169 #endif