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" );
96 if ((len
= read( fd
, buf
, sizeof(buf
) )) <= 0) {
97 fprintf( stderr
, "Cannot receive reply\n" );
100 if (len
== sizeof(buf
) && buf
[sizeof(buf
) - 1] != '\n')
101 fprintf( stderr
, "Warning: reply is too long\n" );
102 fwrite( buf
, 1, len
, stdout
);
103 if (len
== sizeof(buf
) && buf
[sizeof(buf
) - 1] != '\n')
109 run( int fd
, char **argv
)
115 return exe( fd
, "caps\n", 5 );
116 if (!strcmp( *argv
, "-" )) {
119 fputs( "> ", stdout
);
122 if (!fgets( buf
, sizeof(buf
), stdin
))
124 if (exe( fd
, buf
, strlen( buf
) ))
128 len
= strlen( *argv
);
129 if (len
>= sizeof(buf
))
131 memcpy( buf
, *argv
, len
);
134 if (len
+ l
+ 1 >= sizeof(buf
))
137 memcpy( buf
+ len
, *argv
, l
);
141 return exe( fd
, buf
, len
);
143 fprintf( stderr
, "Command too long\n" );
149 main( int argc
, char **argv
)
151 char *dpy
= getenv( "DISPLAY" );
152 const char *ctl
= getenv( "DM_CONTROL" );
153 const char *cfg
= KDE_CONFDIR
"/kdm/kdmrc";
160 if (*ptr
!= '-' || !*(ptr
+ 1))
165 if (!strcmp( ptr
, "h" ) || !strcmp( ptr
, "help" )) {
167 "Usage: kdmctl [options] [command [command arguments]]\n"
170 " -h -help This help message.\n"
171 " -g -global Use global control socket even if $DISPLAY is set\n"
172 " -d -display Override $DISPLAY\n"
173 " -s -sockets Override $DM_CONTROL\n"
174 " -c -config Use alternative kdm config file\n"
176 "The directory in which the sockets are located is determined this way:\n"
177 "- the -s option is examined\n"
178 "- the $DM_CONTROL variable is examined\n"
179 "- the kdm config file is searched for the FifoDir key\n"
180 "- /var/run/xdmctl and /var/run are tried\n"
182 "If $DISPLAY is set (or -d was specified) and -g was not specified, the\n"
183 "display-specific control socket will be used, otherwise the global one.\n"
185 "Tokens in the command and the reply are tab-separated.\n"
186 "Command arguments can be specified as separate command line parameters,\n"
187 "in which case they are simply concatenated with tabs in between.\n"
189 "If the command is '-', kdmctl reads commands from stdin.\n"
190 "The default command is 'caps'.\n"
193 } else if (!strcmp( ptr
, "g" ) || !strcmp( ptr
, "global" ))
195 else if (!strcmp( ptr
, "d" ) || !strcmp( ptr
, "display" )) {
199 } else if (!strcmp( ptr
, "s" ) || !strcmp( ptr
, "sockets" )) {
203 } else if (!strcmp( ptr
, "c" ) || !strcmp( ptr
, "config" )) {
206 fprintf( stderr
, "Option '%s' needs argument.\n",
212 fprintf( stderr
, "Unknown option '%s'.\n", ptr
);
216 if ((!ctl
|| !*ctl
) && *cfg
)
217 ctl
= readConfig( cfg
);
218 if ((fd
= socket( PF_UNIX
, SOCK_STREAM
, 0 )) < 0) {
219 fprintf( stderr
, "Cannot create UNIX socket\n" );
222 if (dpy
&& (ptr
= strchr( dpy
, ':' )) && (ptr
= strchr( ptr
, '.' )))
225 if (!openCtl( fd
, 1, ctl
, dpy
))
228 if (!openCtl( fd
, 0, "/var/run/xdmctl", dpy
) &&
229 !openCtl( fd
, 0, "/var/run", dpy
))
231 fprintf( stderr
, "No command socket found.\n" );
235 return run( fd
, argv
);