ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtd.C
Revision: 1.9
Committed: Fri Feb 13 13:28:17 2004 UTC (20 years, 4 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_1_0, rel-2_4, rel-2_2, rel-2_3, rel-2_0, rel-1_9
Changes since 1.8: +12 -9 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "../config.h"
2 #include "rxvt.h"
3 #include "rxvtdaemon.h"
4 #include "iom.h"
5
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstdarg>
9 #include <cstring>
10
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/socket.h>
15 #include <sys/un.h>
16
17 #include <cerrno>
18
19 extern char **environ;
20
21 struct server : rxvt_connection {
22 void read_cb (io_watcher &w, short revents); io_watcher read_ev;
23
24 server (int fd)
25 : read_ev (this, &server::read_cb)
26 {
27 this->fd = fd;
28 read_ev.start (fd, EVENT_READ);
29 }
30
31 void err (const char *format = 0, ...);
32 };
33
34 struct unix_listener {
35 int fd;
36
37 void accept_cb (io_watcher &w, short revents); io_watcher accept_ev;
38
39 unix_listener (const char *sockname);
40 };
41
42 unix_listener::unix_listener (const char *sockname)
43 : accept_ev (this, &unix_listener::accept_cb)
44 {
45 if ((fd = socket (PF_LOCAL, SOCK_STREAM, 0)) < 0)
46 {
47 perror ("unable to create listening socket");
48 exit (EXIT_FAILURE);
49 }
50
51 sockaddr_un sa;
52
53 sa.sun_family = AF_UNIX;
54 strcpy (sa.sun_path, sockname);
55
56 unlink (rxvt_connection::unix_sockname ());
57
58 mode_t omask = umask (0077);
59
60 if (bind (fd, (sockaddr *)&sa, sizeof (sa)))
61 {
62 perror ("unable to bind listening socket");
63 exit (EXIT_FAILURE);
64 }
65
66 umask (omask);
67
68 if (listen (fd, 5))
69 {
70 perror ("unable to listen on socket");
71 exit (EXIT_FAILURE);
72 }
73
74 accept_ev.start (fd, EVENT_READ);
75 }
76
77 void unix_listener::accept_cb (io_watcher &w, short revents)
78 {
79 int fd2 = accept (fd, 0, 0);
80
81 if (fd2 >= 0)
82 new server (fd2);
83 }
84
85 void server::err (const char *format, ...)
86 {
87 if (format)
88 {
89 char err[1024];
90
91 va_list ap;
92 va_start (ap, format);
93 vsnprintf (err, 1024, format, ap);
94 va_end (ap);
95
96 send ("ERR"), send (err);
97 }
98
99 close (fd);
100 delete this;
101 }
102
103 void server::read_cb (io_watcher &w, short revents)
104 {
105 auto_str tok;
106
107 if (recv (tok))
108 {
109 if (!strcmp (tok, "NEW"))
110 {
111 stringvec *argv = new stringvec;
112 stringvec *envv = new stringvec;
113
114 for (;;)
115 {
116 if (!recv (tok))
117 return err ();
118
119 if (!strcmp (tok, "END"))
120 break;
121 else if (!strcmp (tok, "ENV") && recv (tok))
122 envv->push_back (tok.get ());
123 else if (!strcmp (tok, "CWD") && recv (tok))
124 {
125 if (chdir (tok))
126 err ("unable to change to working directory to '%s': %s",
127 (char *)tok, strerror (errno));
128 }
129 else if (!strcmp (tok, "ARG") && recv (tok))
130 argv->push_back (tok.get ());
131 else
132 return err ("protocol error: unexpected NEW token");
133 }
134
135 envv->push_back (0);
136
137 {
138 char **old_environ = environ;
139 environ = envv->begin ();
140
141 rxvt_term *term = rxvt_init (argv->size (), argv->begin ());
142
143 term->argv = argv;
144 term->envv = envv;
145
146 environ = old_environ;
147 }
148 }
149 else
150 return err ("protocol error: request '%s' unsupported.", (char *)tok);
151 }
152 else
153 return err ();
154 }
155
156 int
157 main (int argc, const char *const *argv)
158 {
159 rxvt_init_signals ();
160
161 char *sockname = rxvt_connection::unix_sockname ();
162 unix_listener l (sockname);
163 printf ("rxvtd listening on %s.\n", sockname);
164 free (sockname);
165
166 iom.loop ();
167
168 #if 0
169 if (rxvt_init (argc, argv) == NULL)
170 return EXIT_FAILURE;
171
172 dR;
173 rxvt_main_loop (aR); /* main processing loop */
174 #endif
175 return EXIT_SUCCESS;
176 }
177