3 * Fvwm command input interface.
5 * Copyright 1996, Toshi Isogai. No guarantees or warantees or anything
6 * are provided. Use this program at your own risk. Permission to use
7 * this program for any purpose is given,
8 * as long as the copyright is kept intact.
11 /* This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /* FIXME: The signal handling of this module is largely broken */
30 #include "FvwmConsole.h"
32 #include "libs/fvwmsignal.h"
34 /* using ParseModuleArgs now */
35 static ModuleArgs
* module
;
37 int Fd
[2]; /* pipe to fvwm */
38 int Ns
= -1; /* socket handles */
39 char Name
[80]; /* name of this program in executable format */
40 char *S_name
= NULL
; /* socket name */
43 RETSIGTYPE
DeadPipe(int);
44 void ErrMsg(char *msg
);
66 RETSIGTYPE
DeadPipe(int dummy
)
74 RETSIGTYPE
SigHandler(int dummy
)
82 RETSIGTYPE
ReapChildren(int sig
)
84 fvwmReapChildren(sig
);
89 int main(int argc
, char *argv
[])
94 char *xterm_pre
[] = { "-title", Name
, "-name", Name
, NULL
};
95 char *xterm_post
[] = { "-e", NULL
, NULL
};
98 /* Why is this not just put in the initializer of xterm_a?
99 * Apparently, it is a non-standard extension to use a non-constant
100 * address (of client) in an initializer (of xterm_a).
102 xterm_post
[1] = client
;
104 module
= ParseModuleArgs(argc
, argv
, 0); /* we don't use an alias */
108 stderr
, "FvwmConsole version "VERSION
" should only be"
109 " executed by fvwm!\n");
112 strcpy(Name
, module
->name
);
113 /* construct client's name */
114 strcpy(client
, argv
[0]);
116 eargv
=(char **)safemalloc((argc
+12)*sizeof(char *));
120 for (k
= 0; xterm_pre
[k
] != NULL
; j
++, k
++)
122 eargv
[j
] = xterm_pre
[k
];
124 for (i
= 0; i
< module
->user_argc
; i
++)
126 if (!strcmp(module
->user_argv
[i
], "-e"))
131 else if (!strcmp(module
->user_argv
[i
], "-terminal"))
134 if (i
< module
->user_argc
)
135 /* use alternative terminal emulator */
136 eargv
[0] = module
->user_argv
[i
];
140 eargv
[j
++] = module
->user_argv
[i
];
143 for (k
= 0; xterm_post
[k
] != NULL
; j
++, k
++)
145 eargv
[j
] = xterm_post
[k
];
148 /* copy rest of -e args */
149 for (; i
<module
->user_argc
; i
++, j
++)
151 eargv
[j
-1] = module
->user_argv
[i
];
154 signal(SIGCHLD
, ReapChildren
);
155 /* Dead pipes mean fvwm died */
156 signal(SIGPIPE
, DeadPipe
);
157 signal(SIGINT
, SigHandler
);
158 signal(SIGQUIT
, SigHandler
);
159 signal(SIGALRM
, SigHandler
);
161 Fd
[0] = module
->to_fvwm
;
162 Fd
[1] = module
->from_fvwm
;
164 /* launch xterm with client */
168 ErrMsg("client forking");
172 execvp(*eargv
, eargv
);
175 /* tell fvwm we're running */
176 SendFinishedStartupNotification(Fd
);
184 * setup server and communicate with fvwm and the client
188 struct sockaddr_un sas
, csas
;
190 socklen_t clen
; /* length of sockaddr */
191 char buf
[MAX_COMMAND_SIZE
]; /* command line buffer */
201 s
= socket(AF_UNIX
, SOCK_STREAM
, 0);
207 /* name the socket */
208 home
= getenv("FVWM_USERDIR");
209 S_name
= safemalloc(strlen(home
) + sizeof(S_NAME
) + 1);
210 strcpy(S_name
, home
);
211 strcat(S_name
, S_NAME
);
213 sas
.sun_family
= AF_UNIX
;
214 strcpy(sas
.sun_path
, S_name
);
215 /* bind the above name to the socket: first, erase the old socket */
217 len
= sizeof(sas
) - sizeof(sas
.sun_path
) + strlen(sas
.sun_path
);
219 rc
= bind(s
, (struct sockaddr
*)&sas
, len
);
226 /* don't wait forever for connections */
227 alarm(FVWMCONSOLE_CONNECTION_TO_SECS
);
228 /* listen to the socket */
235 /* accept connections */
237 Ns
= accept(s
, (struct sockaddr
*)&csas
, &clen
);
243 /* send config lines to Client */
245 fvwm_send(Ns
, C_BEG
, strlen(C_BEG
), 0);
246 GetConfigLine(Fd
, &tline
);
247 while (tline
!= NULL
)
249 if (strlen(tline
) > 1)
251 fvwm_send(Ns
, tline
, strlen(tline
), 0);
252 fvwm_send(Ns
, "\n", 1, 0);
254 GetConfigLine(Fd
, &tline
);
256 fvwm_send(Ns
, C_END
, strlen(C_END
), 0);
258 strcpy(ver
, module
->name
);
259 strcat(ver
, " version ");
260 strcat(ver
, VERSION VERSIONINFO
);
262 fvwm_send(Ns
, ver
, strlen(ver
), 0);
268 FD_SET(Fd
[1], &fdset
);
270 fvwmSelect(FD_SETSIZE
, SELECT_FD_SET_CAST
&fdset
, 0, 0, NULL
);
271 if (FD_ISSET(Fd
[1], &fdset
))
273 FvwmPacket
* packet
= ReadFvwmPacket(Fd
[1]);
282 if (packet
->type
== M_PASS
)
285 (char *)&(packet
->body
[3]));
286 if (msglen
> MAX_MESSAGE_SIZE
-2)
288 msglen
= MAX_MESSAGE_SIZE
-2;
291 Ns
, (char *)&(packet
->body
[3]),
296 if (FD_ISSET(Ns
, &fdset
))
301 rc
= fvwm_recv(Ns
, buf
, MAX_COMMAND_SIZE
, 0);
304 /* client is terminated */
308 /* process the own unique commands */
310 if (len
> 0 && buf
[len
- 1] == '\n')
315 SendText(Fd
, buf
, 0);
321 * print error message on stderr and exit
323 void ErrMsg(char *msg
)
326 stderr
, "%s server error in %s, errno %d: %s\n", Name
, msg
,
327 errno
, strerror(errno
));