~ubuntu-branches/ubuntu/saucy/wicd/saucy

« back to all changes in this revision

Viewing changes to depends/python-wpactrl/wpa_ctrl.c

  • Committer: Bazaar Package Importer
  • Author(s): David Paleino
  • Date: 2009-06-22 17:59:27 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090622175927-iax3alden0bmj6zg
Tags: 1.6.1-3
* debian/config, debian/templates updated:
  - only show users to add to netdev, skip those who are already
    members (Closes: #534138)
  - gracefully handle upgrades from previous broken versions, where
    debconf set a value of ${default} for wicd/users
    (Closes: #532112)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Modifed version of src/common/wpa_ctrl.c from wpa_supplicant, discarding
 
3
 * all code paths except for CONFIG_CTRL_IFACE_UNIX. Define strlcpy inline,
 
4
 * it is not provided by GNU libc.
 
5
 * Copyright (c) 2008, Kel Modderman <kel@otaku42.de>
 
6
 *
 
7
 * wpa_supplicant/hostapd control interface library
 
8
 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License version 2 as
 
12
 * published by the Free Software Foundation.
 
13
 *
 
14
 * Alternatively, this software may be distributed under the terms of BSD
 
15
 * license.
 
16
 */
 
17
 
 
18
#include <stdlib.h>
 
19
#include <stdio.h>
 
20
#include <stdarg.h>
 
21
#include <string.h>
 
22
#include <unistd.h>
 
23
#include <netinet/in.h>
 
24
#include <sys/socket.h>
 
25
#include <sys/time.h>
 
26
#include <sys/types.h>
 
27
#include <sys/un.h>
 
28
 
 
29
#include "wpa_ctrl.h"
 
30
 
 
31
/**
 
32
 * strlcpy - Copy a string with size bound and NUL-termination
 
33
 * @dest: Destination
 
34
 * @src: Source
 
35
 * @siz: Size of the target buffer
 
36
 * Returns: Total length of the target string (length of src) (not including
 
37
 * NUL-termination)
 
38
 *
 
39
 * This function matches in behavior with the strlcpy(3) function in OpenBSD.
 
40
 */
 
41
size_t strlcpy(char *dest, const char *src, size_t siz)
 
42
{
 
43
        const char *s = src;
 
44
        size_t left = siz;
 
45
 
 
46
        if (left) {
 
47
                /* Copy string up to the maximum size of the dest buffer */
 
48
                while (--left != 0) {
 
49
                        if ((*dest++ = *s++) == '\0')
 
50
                                break;
 
51
                }
 
52
        }
 
53
 
 
54
        if (left == 0) {
 
55
                /* Not enough room for the string; force NUL-termination */
 
56
                if (siz != 0)
 
57
                        *dest = '\0';
 
58
                while (*s++)
 
59
                        ; /* determine total src string length */
 
60
        }
 
61
 
 
62
        return s - src - 1;
 
63
}
 
64
 
 
65
 
 
66
/**
 
67
 * struct wpa_ctrl - Internal structure for control interface library
 
68
 *
 
69
 * This structure is used by the wpa_supplicant/hostapd control interface
 
70
 * library to store internal data. Programs using the library should not touch
 
71
 * this data directly. They can only use the pointer to the data structure as
 
72
 * an identifier for the control interface connection and use this as one of
 
73
 * the arguments for most of the control interface library functions.
 
74
 */
 
75
struct wpa_ctrl {
 
76
        int s;
 
77
        struct sockaddr_un local;
 
78
        struct sockaddr_un dest;
 
79
};
 
80
 
 
81
 
 
82
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
 
83
{
 
84
        struct wpa_ctrl *ctrl;
 
85
        static int counter = 0;
 
86
        int ret;
 
87
        size_t res;
 
88
 
 
89
        ctrl = malloc(sizeof(*ctrl));
 
90
        if (ctrl == NULL)
 
91
                return NULL;
 
92
        memset(ctrl, 0, sizeof(*ctrl));
 
93
 
 
94
        ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
 
95
        if (ctrl->s < 0) {
 
96
                free(ctrl);
 
97
                return NULL;
 
98
        }
 
99
 
 
100
        ctrl->local.sun_family = AF_UNIX;
 
101
        ret = snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
 
102
                          "/tmp/wpa_ctrl_%d-%d", getpid(), counter++);
 
103
        if (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) {
 
104
                close(ctrl->s);
 
105
                free(ctrl);
 
106
                return NULL;
 
107
        }
 
108
        if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
 
109
                    sizeof(ctrl->local)) < 0) {
 
110
                close(ctrl->s);
 
111
                free(ctrl);
 
112
                return NULL;
 
113
        }
 
114
 
 
115
        ctrl->dest.sun_family = AF_UNIX;
 
116
        res = strlcpy(ctrl->dest.sun_path, ctrl_path,
 
117
                         sizeof(ctrl->dest.sun_path));
 
118
        if (res >= sizeof(ctrl->dest.sun_path)) {
 
119
                close(ctrl->s);
 
120
                free(ctrl);
 
121
                return NULL;
 
122
        }
 
123
        if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
 
124
                    sizeof(ctrl->dest)) < 0) {
 
125
                close(ctrl->s);
 
126
                unlink(ctrl->local.sun_path);
 
127
                free(ctrl);
 
128
                return NULL;
 
129
        }
 
130
 
 
131
        return ctrl;
 
132
}
 
133
 
 
134
 
 
135
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
 
136
{
 
137
        unlink(ctrl->local.sun_path);
 
138
        close(ctrl->s);
 
139
        free(ctrl);
 
140
}
 
141
 
 
142
 
 
143
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
 
144
                     char *reply, size_t *reply_len,
 
145
                     void (*msg_cb)(char *msg, size_t len))
 
146
{
 
147
        struct timeval tv;
 
148
        int res;
 
149
        fd_set rfds;
 
150
        const char *_cmd;
 
151
        char *cmd_buf = NULL;
 
152
        size_t _cmd_len;
 
153
 
 
154
        {
 
155
                _cmd = cmd;
 
156
                _cmd_len = cmd_len;
 
157
        }
 
158
 
 
159
        if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
 
160
                free(cmd_buf);
 
161
                return -1;
 
162
        }
 
163
        free(cmd_buf);
 
164
 
 
165
        for (;;) {
 
166
                tv.tv_sec = 2;
 
167
                tv.tv_usec = 0;
 
168
                FD_ZERO(&rfds);
 
169
                FD_SET(ctrl->s, &rfds);
 
170
                res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
 
171
                if (FD_ISSET(ctrl->s, &rfds)) {
 
172
                        res = recv(ctrl->s, reply, *reply_len, 0);
 
173
                        if (res < 0)
 
174
                                return res;
 
175
                        if (res > 0 && reply[0] == '<') {
 
176
                                /* This is an unsolicited message from
 
177
                                 * wpa_supplicant, not the reply to the
 
178
                                 * request. Use msg_cb to report this to the
 
179
                                 * caller. */
 
180
                                if (msg_cb) {
 
181
                                        /* Make sure the message is nul
 
182
                                         * terminated. */
 
183
                                        if ((size_t) res == *reply_len)
 
184
                                                res = (*reply_len) - 1;
 
185
                                        reply[res] = '\0';
 
186
                                        msg_cb(reply, res);
 
187
                                }
 
188
                                continue;
 
189
                        }
 
190
                        *reply_len = res;
 
191
                        break;
 
192
                } else {
 
193
                        return -2;
 
194
                }
 
195
        }
 
196
        return 0;
 
197
}
 
198
 
 
199
 
 
200
static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
 
201
{
 
202
        char buf[10];
 
203
        int ret;
 
204
        size_t len = 10;
 
205
 
 
206
        ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
 
207
                               buf, &len, NULL);
 
208
        if (ret < 0)
 
209
                return ret;
 
210
        if (len == 3 && memcmp(buf, "OK\n", 3) == 0)
 
211
                return 0;
 
212
        return -1;
 
213
}
 
214
 
 
215
 
 
216
int wpa_ctrl_attach(struct wpa_ctrl *ctrl)
 
217
{
 
218
        return wpa_ctrl_attach_helper(ctrl, 1);
 
219
}
 
220
 
 
221
 
 
222
int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
 
223
{
 
224
        return wpa_ctrl_attach_helper(ctrl, 0);
 
225
}
 
226
 
 
227
 
 
228
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
 
229
{
 
230
        int res;
 
231
 
 
232
        res = recv(ctrl->s, reply, *reply_len, 0);
 
233
        if (res < 0)
 
234
                return res;
 
235
        *reply_len = res;
 
236
        return 0;
 
237
}
 
238
 
 
239
 
 
240
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
 
241
{
 
242
        struct timeval tv;
 
243
        fd_set rfds;
 
244
        tv.tv_sec = 0;
 
245
        tv.tv_usec = 0;
 
246
        FD_ZERO(&rfds);
 
247
        FD_SET(ctrl->s, &rfds);
 
248
        select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
 
249
        return FD_ISSET(ctrl->s, &rfds);
 
250
}
 
251
 
 
252
 
 
253
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
 
254
{
 
255
        return ctrl->s;
 
256
}