~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kdm/kfrontend/kdmctl.c

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
KDM remote control application
 
4
 
 
5
Copyright (C) 2004 Oswald Buddenhagen <ossi@kde.org>
 
6
 
 
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.
 
11
 
 
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.
 
16
 
 
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.
 
20
 
 
21
*/
 
22
 
 
23
#include <config-workspace.h>
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <unistd.h>
 
28
#include <string.h>
 
29
#include <ctype.h>
 
30
#include <sys/socket.h>
 
31
#include <sys/un.h>
 
32
 
 
33
static int
 
34
openCtl(int fd, int err, const char *ctl, const char *dpy)
 
35
{
 
36
    struct sockaddr_un sa;
 
37
 
 
38
    sa.sun_family = AF_UNIX;
 
39
    if (dpy)
 
40
        snprintf(sa.sun_path, sizeof(sa.sun_path),
 
41
                 "%s/dmctl-%s/socket", ctl, dpy);
 
42
    else
 
43
        snprintf(sa.sun_path, sizeof(sa.sun_path),
 
44
                 "%s/dmctl/socket", ctl);
 
45
    if (!connect(fd, (struct sockaddr *)&sa, sizeof(sa)))
 
46
        return 1;
 
47
    if (err)
 
48
        fprintf(stderr, "Cannot connect socket '%s'.\n", sa.sun_path);
 
49
    return 0;
 
50
}
 
51
 
 
52
static const char *
 
53
readConfig(const char *cfg)
 
54
{
 
55
    FILE *fp;
 
56
    const char *ctl;
 
57
    char *ptr, *ptr2;
 
58
    char buf[1024];
 
59
 
 
60
    if (!(fp = fopen(cfg, "r"))) {
 
61
        fprintf(stderr,
 
62
                "Cannot open kdm config file '%s'.\n",
 
63
                cfg);
 
64
        return 0;
 
65
    }
 
66
    ctl = "/var/run/xdmctl";
 
67
    while (fgets(buf, sizeof(buf), fp))
 
68
        if (!strncmp(buf, "FifoDir", 7)) {
 
69
            ptr = buf + 7;
 
70
            while (*ptr && isspace(*ptr))
 
71
                ptr++;
 
72
            if (*ptr++ != '=')
 
73
                continue;
 
74
            while (*ptr && isspace(*ptr))
 
75
                ptr++;
 
76
            for (ptr2 = buf + strlen(buf);
 
77
                 ptr2 > ptr && isspace(*(ptr2 - 1));
 
78
                 ptr2--);
 
79
            *ptr2 = 0;
 
80
            ctl = strdup(ptr);
 
81
            break;
 
82
        }
 
83
    fclose(fp);
 
84
    return ctl;
 
85
}
 
86
 
 
87
static int
 
88
exe(int fd, const char *in, int len)
 
89
{
 
90
    char buf[4096];
 
91
 
 
92
    if (write(fd, in, len) != len) {
 
93
        fprintf(stderr, "Cannot send command\n");
 
94
        return 1;
 
95
    }
 
96
    do {
 
97
        if ((len = read(fd, buf, sizeof(buf))) <= 0) {
 
98
            fprintf(stderr, "Cannot receive reply\n");
 
99
            return 1;
 
100
        }
 
101
        fwrite(buf, 1, len, stdout);
 
102
    } while (buf[len - 1] != '\n');
 
103
    return 0;
 
104
}
 
105
 
 
106
static int
 
107
run(int fd, char **argv)
 
108
{
 
109
    unsigned len, l;
 
110
    char buf[1024];
 
111
 
 
112
    if (!*argv)
 
113
        return exe(fd, "caps\n", 5);
 
114
    if (!strcmp(*argv, "-")) {
 
115
        for (;;) {
 
116
            if (isatty(0)) {
 
117
                fputs("> ", stdout);
 
118
                fflush(stdout);
 
119
            }
 
120
            if (!fgets(buf, sizeof(buf), stdin))
 
121
                return 0;
 
122
            if (exe(fd, buf, strlen(buf)))
 
123
                return 1;
 
124
        }
 
125
    } else {
 
126
        len = strlen(*argv);
 
127
        if (len >= sizeof(buf))
 
128
            goto bad;
 
129
        memcpy(buf, *argv, len);
 
130
        while (*++argv) {
 
131
            l = strlen(*argv);
 
132
            if (len + l + 1 >= sizeof(buf))
 
133
                goto bad;
 
134
            buf[len++] = '\t';
 
135
            memcpy(buf + len, *argv, l);
 
136
            len += l;
 
137
        }
 
138
        buf[len++] = '\n';
 
139
        return exe(fd, buf, len);
 
140
      bad:
 
141
        fprintf(stderr, "Command too long\n");
 
142
        return 1;
 
143
    }
 
144
}
 
145
 
 
146
int
 
147
main(int argc, char **argv)
 
148
{
 
149
    char *dpy = getenv("DISPLAY");
 
150
    const char *ctl = getenv("DM_CONTROL");
 
151
    const char *cfg = KDE_CONFDIR "/kdm/kdmrc";
 
152
    char *ptr;
 
153
    int fd;
 
154
 
 
155
    (void)argc;
 
156
    while (*++argv) {
 
157
        ptr = *argv;
 
158
        if (*ptr != '-' || !*(ptr + 1))
 
159
            break;
 
160
        ptr++;
 
161
        if (*ptr == '-')
 
162
            ptr++;
 
163
        if (!strcmp(ptr, "h") || !strcmp(ptr, "help")) {
 
164
            puts(
 
165
"Usage: kdmctl [options] [command [command arguments]]\n"
 
166
"\n"
 
167
"Options are:\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"
 
173
"\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"
 
179
"\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"
 
182
"\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"
 
186
"\n"
 
187
"If the command is '-', kdmctl reads commands from stdin.\n"
 
188
"The default command is 'caps'.\n"
 
189
           );
 
190
            return 0;
 
191
        } else if (!strcmp(ptr, "g") || !strcmp(ptr, "global")) {
 
192
            dpy = 0;
 
193
        } else if (!strcmp(ptr, "d") || !strcmp(ptr, "display")) {
 
194
            if (!argv[1])
 
195
                goto needarg;
 
196
            dpy = *++argv;
 
197
        } else if (!strcmp(ptr, "s") || !strcmp(ptr, "sockets")) {
 
198
            if (!argv[1])
 
199
                goto needarg;
 
200
            ctl = *++argv;
 
201
        } else if (!strcmp(ptr, "c") || !strcmp(ptr, "config")) {
 
202
            if (!argv[1]) {
 
203
              needarg:
 
204
                fprintf(stderr, "Option '%s' needs argument.\n", ptr);
 
205
                return 1;
 
206
            }
 
207
            cfg = *++argv;
 
208
        } else {
 
209
            fprintf(stderr, "Unknown option '%s'.\n", ptr);
 
210
            return 1;
 
211
        }
 
212
    }
 
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");
 
217
        return 1;
 
218
    }
 
219
    if (dpy && (ptr = strchr(dpy, ':')) && (ptr = strchr(ptr, '.')))
 
220
        *ptr = 0;
 
221
    if (ctl && *ctl) {
 
222
        if (!openCtl(fd, 1, ctl, dpy))
 
223
            return 1;
 
224
    } else {
 
225
        if (!openCtl(fd, 0, "/var/run/xdmctl", dpy) &&
 
226
            !openCtl(fd, 0, "/var/run", dpy))
 
227
        {
 
228
            fprintf(stderr, "No command socket found.\n");
 
229
            return 1;
 
230
        }
 
231
    }
 
232
    return run(fd, argv);
 
233
}