3
KDM remote control application
5
Copyright (C) 2004 Oswald Buddenhagen <ossi@kde.org>
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
#include <config-workspace.h>
30
#include <sys/socket.h>
34
openCtl(int fd, int err, const char *ctl, const char *dpy)
36
struct sockaddr_un sa;
38
sa.sun_family = AF_UNIX;
40
snprintf(sa.sun_path, sizeof(sa.sun_path),
41
"%s/dmctl-%s/socket", ctl, dpy);
43
snprintf(sa.sun_path, sizeof(sa.sun_path),
44
"%s/dmctl/socket", ctl);
45
if (!connect(fd, (struct sockaddr *)&sa, sizeof(sa)))
48
fprintf(stderr, "Cannot connect socket '%s'.\n", sa.sun_path);
53
readConfig(const char *cfg)
60
if (!(fp = fopen(cfg, "r"))) {
62
"Cannot open kdm config file '%s'.\n",
66
ctl = "/var/run/xdmctl";
67
while (fgets(buf, sizeof(buf), fp))
68
if (!strncmp(buf, "FifoDir", 7)) {
70
while (*ptr && isspace(*ptr))
74
while (*ptr && isspace(*ptr))
76
for (ptr2 = buf + strlen(buf);
77
ptr2 > ptr && isspace(*(ptr2 - 1));
88
exe(int fd, const char *in, int len)
92
if (write(fd, in, len) != len) {
93
fprintf(stderr, "Cannot send command\n");
97
if ((len = read(fd, buf, sizeof(buf))) <= 0) {
98
fprintf(stderr, "Cannot receive reply\n");
101
fwrite(buf, 1, len, stdout);
102
} while (buf[len - 1] != '\n');
107
run(int fd, char **argv)
113
return exe(fd, "caps\n", 5);
114
if (!strcmp(*argv, "-")) {
120
if (!fgets(buf, sizeof(buf), stdin))
122
if (exe(fd, buf, strlen(buf)))
127
if (len >= sizeof(buf))
129
memcpy(buf, *argv, len);
132
if (len + l + 1 >= sizeof(buf))
135
memcpy(buf + len, *argv, l);
139
return exe(fd, buf, len);
141
fprintf(stderr, "Command too long\n");
147
main(int argc, char **argv)
149
char *dpy = getenv("DISPLAY");
150
const char *ctl = getenv("DM_CONTROL");
151
const char *cfg = KDE_CONFDIR "/kdm/kdmrc";
158
if (*ptr != '-' || !*(ptr + 1))
163
if (!strcmp(ptr, "h") || !strcmp(ptr, "help")) {
165
"Usage: kdmctl [options] [command [command arguments]]\n"
168
" -h -help This help message.\n"
169
" -g -global Use global control socket even if $DISPLAY is set\n"
170
" -d -display Override $DISPLAY\n"
171
" -s -sockets Override $DM_CONTROL\n"
172
" -c -config Use alternative kdm config file\n"
174
"The directory in which the sockets are located is determined this way:\n"
175
"- the -s option is examined\n"
176
"- the $DM_CONTROL variable is examined\n"
177
"- the kdm config file is searched for the FifoDir key\n"
178
"- /var/run/xdmctl and /var/run are tried\n"
180
"If $DISPLAY is set (or -d was specified) and -g was not specified, the\n"
181
"display-specific control socket will be used, otherwise the global one.\n"
183
"Tokens in the command and the reply are tab-separated.\n"
184
"Command arguments can be specified as separate command line parameters,\n"
185
"in which case they are simply concatenated with tabs in between.\n"
187
"If the command is '-', kdmctl reads commands from stdin.\n"
188
"The default command is 'caps'.\n"
191
} else if (!strcmp(ptr, "g") || !strcmp(ptr, "global")) {
193
} else if (!strcmp(ptr, "d") || !strcmp(ptr, "display")) {
197
} else if (!strcmp(ptr, "s") || !strcmp(ptr, "sockets")) {
201
} else if (!strcmp(ptr, "c") || !strcmp(ptr, "config")) {
204
fprintf(stderr, "Option '%s' needs argument.\n", ptr);
209
fprintf(stderr, "Unknown option '%s'.\n", ptr);
213
if ((!ctl || !*ctl) && *cfg)
214
ctl = readConfig(cfg);
215
if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
216
fprintf(stderr, "Cannot create UNIX socket\n");
219
if (dpy && (ptr = strchr(dpy, ':')) && (ptr = strchr(ptr, '.')))
222
if (!openCtl(fd, 1, ctl, dpy))
225
if (!openCtl(fd, 0, "/var/run/xdmctl", dpy) &&
226
!openCtl(fd, 0, "/var/run", dpy))
228
fprintf(stderr, "No command socket found.\n");
232
return run(fd, argv);