… | |
… | |
2 | #include "rxvtdaemon.h" |
2 | #include "rxvtdaemon.h" |
3 | #include "iom.h" |
3 | #include "iom.h" |
4 | |
4 | |
5 | #include <cstdio> |
5 | #include <cstdio> |
6 | #include <cstdlib> |
6 | #include <cstdlib> |
|
|
7 | #include <cstdarg> |
|
|
8 | #include <cstring> |
7 | |
9 | |
8 | #include <unistd.h> |
10 | #include <unistd.h> |
9 | #include <sys/socket.h> |
11 | #include <sys/socket.h> |
10 | #include <sys/un.h> |
12 | #include <sys/un.h> |
|
|
13 | |
|
|
14 | #include <cerrno> |
|
|
15 | |
|
|
16 | extern char **environ; |
11 | |
17 | |
12 | struct server : rxvt_connection { |
18 | struct server : rxvt_connection { |
13 | void read_cb (io_watcher &w, short revents); io_watcher read_ev; |
19 | void read_cb (io_watcher &w, short revents); io_watcher read_ev; |
14 | |
20 | |
15 | server (int fd) |
21 | server (int fd) |
… | |
… | |
17 | { |
23 | { |
18 | this->fd = fd; |
24 | this->fd = fd; |
19 | read_ev.start (fd, EVENT_READ); |
25 | read_ev.start (fd, EVENT_READ); |
20 | } |
26 | } |
21 | |
27 | |
22 | void err (); |
28 | void err (const char *format = 0, ...); |
23 | }; |
29 | }; |
24 | |
30 | |
25 | struct listener { |
31 | struct listener { |
26 | int fd; |
32 | int fd; |
27 | |
33 | |
… | |
… | |
67 | |
73 | |
68 | if (fd2 >= 0) |
74 | if (fd2 >= 0) |
69 | new server (fd2); |
75 | new server (fd2); |
70 | } |
76 | } |
71 | |
77 | |
72 | void server::err () |
78 | void server::err (const char *format, ...) |
73 | { |
79 | { |
|
|
80 | if (format) |
|
|
81 | { |
|
|
82 | char err[1024]; |
|
|
83 | |
|
|
84 | va_list ap; |
|
|
85 | va_start (ap, format); |
|
|
86 | vsnprintf (err, 1024, format, ap); |
|
|
87 | va_end (ap); |
|
|
88 | |
|
|
89 | send ("ERR"), send (err); |
|
|
90 | } |
|
|
91 | |
74 | close (fd); |
92 | close (fd); |
75 | delete this; |
93 | delete this; |
76 | } |
94 | } |
77 | |
95 | |
78 | void server::read_cb (io_watcher &w, short revents) |
96 | void server::read_cb (io_watcher &w, short revents) |
… | |
… | |
81 | |
99 | |
82 | if (recv (tok)) |
100 | if (recv (tok)) |
83 | { |
101 | { |
84 | if (!strcmp (tok, "NEW")) |
102 | if (!strcmp (tok, "NEW")) |
85 | { |
103 | { |
86 | auto_str display, cwd; |
104 | stringvec argv; |
87 | simplevec<auto_str> argv; |
105 | stringvec envv; |
88 | |
106 | |
89 | for (;;) |
107 | for (;;) |
90 | { |
108 | { |
91 | if (!recv (tok)) |
109 | if (!recv (tok)) |
92 | return err (); |
110 | return err (); |
93 | |
111 | |
94 | if (!strcmp (tok, "END")) |
112 | if (!strcmp (tok, "END")) |
95 | break; |
113 | break; |
96 | else if (!strcmp (tok, "DISPLAY") && recv (display)) |
114 | else if (!strcmp (tok, "ENV") && recv (tok)) |
97 | ; |
115 | envv.push_back (tok.get ()); |
98 | else if (!strcmp (tok, "CWD") && recv (cwd)) |
116 | else if (!strcmp (tok, "CWD") && recv (tok)) |
99 | ; |
117 | { |
|
|
118 | if (chdir (tok)) |
|
|
119 | err ("unable to change to working directory to '%s': %s", |
|
|
120 | (char *)tok, strerror (errno)); |
|
|
121 | } |
100 | else if (!strcmp (tok, "ARG") && recv (tok)) |
122 | else if (!strcmp (tok, "ARG") && recv (tok)) |
101 | argv.push_back (tok); |
123 | argv.push_back (tok.get ()); |
102 | else |
124 | else |
103 | return err (); |
125 | return err ("protocol error: unexpected NEW token"); |
104 | } |
126 | } |
105 | |
127 | |
106 | // TODO: no setenv, please |
128 | envv.push_back (0); |
107 | setenv ("DISPLAY", display.get (), 1); |
|
|
108 | |
129 | |
|
|
130 | { |
|
|
131 | char **old_environ = environ; |
|
|
132 | environ = envv.begin (); |
|
|
133 | |
109 | rxvt_init (argv.size (), reinterpret_cast<char **>(argv.begin ())); |
134 | rxvt_init (argv.size (), argv.begin ()); |
110 | dR; |
135 | //dR; |
111 | rxvt_main_loop (aR); |
136 | //rxvt_main_loop (aR); |
|
|
137 | |
|
|
138 | environ = old_environ; |
|
|
139 | } |
112 | } |
140 | } |
113 | else |
141 | else |
114 | return err (); |
142 | return err ("protocol error: request '%s' unsupported.", (char *)tok); |
115 | } |
143 | } |
116 | else |
144 | else |
117 | return err (); |
145 | return err (); |
118 | } |
146 | } |
119 | |
147 | |
120 | int |
148 | int |
121 | main(int argc, const char *const *argv) |
149 | main(int argc, const char *const *argv) |
122 | { |
150 | { |
123 | listener l; |
151 | listener l; |
|
|
152 | |
|
|
153 | { |
|
|
154 | sigset_t ss; |
|
|
155 | |
|
|
156 | sigaddset (&ss, SIGHUP); |
|
|
157 | sigprocmask (SIG_BLOCK, &ss, 0); |
|
|
158 | } |
|
|
159 | |
|
|
160 | printf ("rxvtd running.\n"); |
124 | iom.loop (); |
161 | iom.loop (); |
125 | |
162 | |
126 | #if 0 |
163 | #if 0 |
127 | if (rxvt_init(argc, argv) == NULL) |
164 | if (rxvt_init(argc, argv) == NULL) |
128 | return EXIT_FAILURE; |
165 | return EXIT_FAILURE; |