Mercurial > pidgin.yaz
annotate src/protocols/novell/nmconn.c @ 10331:20df7dd1c57c
[gaim-migrate @ 11538]
Something I love about g_string's
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 09 Dec 2004 00:44:58 +0000 |
parents | d77537e8bfe5 |
children | 4b3a952b395e |
rev | line source |
---|---|
8675 | 1 /* |
2 * nmconn.c | |
3 * | |
8933 | 4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved. |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; version 2 of the License. | |
8675 | 9 * |
8933 | 10 * This program is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 * GNU General Public License for more details. | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
14 * |
8933 | 15 * You should have received a copy of the GNU General Public License |
16 * along with this program; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
8675 | 18 * |
19 */ | |
20 | |
21 #include <glib.h> | |
22 #include <unistd.h> | |
23 #include <errno.h> | |
24 #include <string.h> | |
25 #include <ctype.h> | |
26 #include <time.h> | |
27 #include "nmconn.h" | |
28 | |
29 #ifdef _WIN32 | |
30 #include <windows.h> | |
31 #endif | |
32 | |
33 #define NO_ESCAPE(ch) ((ch == 0x20) || (ch >= 0x30 && ch <= 0x39) || \ | |
34 (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a)) | |
35 | |
36 /* Read data from conn until the end of a line */ | |
37 static NMERR_T | |
38 read_line(NMConn * conn, char *buff, int len) | |
39 { | |
40 NMERR_T rc = NM_OK; | |
41 int total_bytes = 0; | |
42 | |
43 while ((rc == NM_OK) && (total_bytes < (len - 1))) { | |
44 rc = nm_read_all(conn, &buff[total_bytes], 1); | |
45 if (rc == NM_OK) { | |
46 total_bytes += 1; | |
47 if (buff[total_bytes - 1] == '\n') { | |
48 break; | |
49 } | |
50 } | |
51 } | |
52 buff[total_bytes] = '\0'; | |
53 | |
54 return rc; | |
55 } | |
56 | |
57 static char * | |
58 url_escape_string(char *src) | |
59 { | |
60 guint32 escape = 0; | |
61 char *p; | |
62 char *q; | |
63 char *encoded = NULL; | |
64 int ch; | |
65 | |
66 static const char hex_table[16] = "0123456789abcdef"; | |
67 | |
68 if (src == NULL) { | |
69 return NULL; | |
70 } | |
71 | |
72 /* Find number of chars to escape */ | |
73 for (p = src; *p != '\0'; p++) { | |
74 ch = (guchar) *p; | |
75 if (!NO_ESCAPE(ch)) { | |
76 escape++; | |
77 } | |
78 } | |
79 | |
80 encoded = g_malloc((p - src) + (escape * 2) + 1); | |
81 | |
82 /* Escape the string */ | |
83 for (p = src, q = encoded; *p != '\0'; p++) { | |
84 ch = (guchar) * p; | |
85 if (NO_ESCAPE(ch)) { | |
86 if (ch != 0x20) { | |
87 *q = ch; | |
88 q++; | |
89 } else { | |
90 *q = '+'; | |
91 q++; | |
92 } | |
93 } else { | |
94 *q = '%'; | |
95 q++; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
96 |
8675 | 97 *q = hex_table[ch >> 4]; |
98 q++; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
99 |
8675 | 100 *q = hex_table[ch & 15]; |
101 q++; | |
102 } | |
103 } | |
104 *q = '\0'; | |
105 | |
106 return encoded; | |
107 } | |
108 | |
109 static char * | |
110 encode_method(guint8 method) | |
111 { | |
112 char *str; | |
113 | |
114 switch (method) { | |
115 case NMFIELD_METHOD_EQUAL: | |
116 str = "G"; | |
117 break; | |
118 case NMFIELD_METHOD_UPDATE: | |
119 str = "F"; | |
120 break; | |
121 case NMFIELD_METHOD_GTE: | |
122 str = "E"; | |
123 break; | |
124 case NMFIELD_METHOD_LTE: | |
125 str = "D"; | |
126 break; | |
127 case NMFIELD_METHOD_NE: | |
128 str = "C"; | |
129 break; | |
130 case NMFIELD_METHOD_EXIST: | |
131 str = "B"; | |
132 break; | |
133 case NMFIELD_METHOD_NOTEXIST: | |
134 str = "A"; | |
135 break; | |
136 case NMFIELD_METHOD_SEARCH: | |
137 str = "9"; | |
138 break; | |
139 case NMFIELD_METHOD_MATCHBEGIN: | |
140 str = "8"; | |
141 break; | |
142 case NMFIELD_METHOD_MATCHEND: | |
143 str = "7"; | |
144 break; | |
145 case NMFIELD_METHOD_NOT_ARRAY: | |
146 str = "6"; | |
147 break; | |
148 case NMFIELD_METHOD_OR_ARRAY: | |
149 str = "5"; | |
150 break; | |
151 case NMFIELD_METHOD_AND_ARRAY: | |
152 str = "4"; | |
153 break; | |
154 case NMFIELD_METHOD_DELETE_ALL: | |
155 str = "3"; | |
156 break; | |
157 case NMFIELD_METHOD_DELETE: | |
158 str = "2"; | |
159 break; | |
160 case NMFIELD_METHOD_ADD: | |
161 str = "1"; | |
162 break; | |
163 default: /* NMFIELD_METHOD_VALID */ | |
164 str = "0"; | |
165 break; | |
166 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
167 |
8675 | 168 return str; |
169 } | |
170 | |
9360 | 171 NMConn * |
172 nm_create_conn(const char *addr, int port) | |
173 { | |
174 NMConn *conn = g_new0(NMConn, 1); | |
175 conn->addr = g_strdup(addr); | |
176 conn->port = port; | |
177 return conn; | |
178 } | |
179 | |
180 void nm_release_conn(NMConn *conn) | |
181 { | |
182 if (conn) { | |
183 GSList *node; | |
184 for (node = conn->requests; node; node = node->next) { | |
185 if (node->data) | |
186 nm_release_request(node->data); | |
187 } | |
188 g_slist_free(conn->requests); | |
189 conn->requests = NULL; | |
190 if (conn->ssl_conn) { | |
191 g_free(conn->ssl_conn); | |
192 conn->ssl_conn = NULL; | |
193 } | |
194 g_free(conn->addr); | |
195 conn->addr = NULL; | |
196 g_free(conn); | |
197 } | |
198 } | |
199 | |
8675 | 200 int |
201 nm_tcp_write(NMConn * conn, const void *buff, int len) | |
202 { | |
203 if (conn == NULL || buff == NULL) | |
204 return -1; | |
205 | |
206 if (!conn->use_ssl) | |
207 return (write(conn->fd, buff, len)); | |
208 else if (conn->ssl_conn && conn->ssl_conn->write) | |
209 return (conn->ssl_conn->write(conn->ssl_conn->data, buff, len)); | |
210 else | |
211 return -1; | |
212 } | |
213 | |
214 int | |
215 nm_tcp_read(NMConn * conn, void *buff, int len) | |
216 { | |
217 if (conn == NULL || buff == NULL) | |
218 return -1; | |
219 | |
220 if (!conn->use_ssl) | |
221 return (read(conn->fd, buff, len)); | |
222 else if (conn->ssl_conn && conn->ssl_conn->read) | |
223 return (conn->ssl_conn->read(conn->ssl_conn->data, buff, len)); | |
224 else | |
225 return -1; | |
226 } | |
227 | |
228 NMERR_T | |
229 nm_read_all(NMConn * conn, char *buff, int len) | |
230 { | |
231 NMERR_T rc = NM_OK; | |
232 int bytes_left = len; | |
233 int bytes_read; | |
234 int total_bytes = 0; | |
235 int retry = 10; | |
236 | |
237 if (conn == NULL || buff == NULL) | |
238 return NMERR_BAD_PARM; | |
239 | |
240 /* Keep reading until buffer is full */ | |
241 while (bytes_left) { | |
242 bytes_read = nm_tcp_read(conn, &buff[total_bytes], bytes_left); | |
243 if (bytes_read > 0) { | |
244 bytes_left -= bytes_read; | |
245 total_bytes += bytes_read; | |
246 } else { | |
247 if (errno == EAGAIN) { | |
248 if (--retry == 0) { | |
249 rc = NMERR_TCP_READ; | |
250 break; | |
251 } | |
252 #ifdef _WIN32 | |
253 Sleep(1000); | |
254 #else | |
255 usleep(1000); | |
256 #endif | |
257 } else { | |
258 rc = NMERR_TCP_READ; | |
259 break; | |
260 } | |
261 } | |
262 } | |
263 return rc; | |
264 } | |
265 | |
266 NMERR_T | |
8874 | 267 nm_read_uint32(NMConn *conn, guint32 *val) |
268 { | |
269 NMERR_T rc = NM_OK; | |
270 | |
271 rc = nm_read_all(conn, (char *)val, sizeof(*val)); | |
272 if (rc == NM_OK) { | |
273 *val = GUINT32_FROM_LE(*val); | |
274 } | |
275 | |
276 return rc; | |
277 } | |
278 | |
279 NMERR_T | |
280 nm_read_uint16(NMConn *conn, guint16 *val) | |
281 { | |
282 NMERR_T rc = NM_OK; | |
283 | |
284 rc = nm_read_all(conn, (char *)val, sizeof(*val)); | |
285 if (rc == NM_OK) { | |
286 *val = GUINT16_FROM_LE(*val); | |
287 } | |
288 | |
289 return rc; | |
290 } | |
291 | |
292 NMERR_T | |
8675 | 293 nm_write_fields(NMConn * conn, NMField * fields) |
294 { | |
295 NMERR_T rc = NM_OK; | |
296 NMField *field; | |
297 char *value = NULL; | |
298 char *method = NULL; | |
8874 | 299 char buffer[4096]; |
8675 | 300 int ret; |
301 int bytes_to_send; | |
302 int val = 0; | |
303 | |
304 if (conn == NULL || fields == NULL) { | |
305 return NMERR_BAD_PARM; | |
306 } | |
307 | |
308 /* Format each field as valid "post" data and write it out */ | |
309 for (field = fields; (rc == NM_OK) && (field->tag); field++) { | |
310 | |
311 /* We don't currently handle binary types */ | |
312 if (field->method == NMFIELD_METHOD_IGNORE || | |
313 field->type == NMFIELD_TYPE_BINARY) { | |
314 continue; | |
315 } | |
316 | |
317 /* Write the field tag */ | |
318 bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&tag=%s", field->tag); | |
319 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
320 if (ret < 0) { | |
321 rc = NMERR_TCP_WRITE; | |
322 } | |
323 | |
324 /* Write the field method */ | |
325 if (rc == NM_OK) { | |
326 method = encode_method(field->method); | |
327 bytes_to_send = g_snprintf(buffer, sizeof(buffer), "&cmd=%s", method); | |
328 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
329 if (ret < 0) { | |
330 rc = NMERR_TCP_WRITE; | |
331 } | |
332 } | |
333 | |
334 /* Write the field value */ | |
335 if (rc == NM_OK) { | |
336 switch (field->type) { | |
337 case NMFIELD_TYPE_UTF8: | |
338 case NMFIELD_TYPE_DN: | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
339 |
8933 | 340 value = url_escape_string((char *) field->ptr_value); |
8675 | 341 bytes_to_send = g_snprintf(buffer, sizeof(buffer), |
342 "&val=%s", value); | |
8874 | 343 if (bytes_to_send > (int)sizeof(buffer)) { |
344 ret = nm_tcp_write(conn, buffer, sizeof(buffer)); | |
345 } else { | |
346 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
347 } | |
348 | |
8675 | 349 if (ret < 0) { |
350 rc = NMERR_TCP_WRITE; | |
351 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
352 |
8675 | 353 g_free(value); |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
354 |
8675 | 355 break; |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
356 |
8675 | 357 case NMFIELD_TYPE_ARRAY: |
358 case NMFIELD_TYPE_MV: | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
359 |
8933 | 360 val = nm_count_fields((NMField *) field->ptr_value); |
8675 | 361 bytes_to_send = g_snprintf(buffer, sizeof(buffer), |
362 "&val=%u", val); | |
363 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
364 if (ret < 0) { | |
365 rc = NMERR_TCP_WRITE; | |
366 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
367 |
8675 | 368 break; |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
369 |
8675 | 370 default: |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
371 |
8675 | 372 bytes_to_send = g_snprintf(buffer, sizeof(buffer), |
373 "&val=%u", field->value); | |
374 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
375 if (ret < 0) { | |
376 rc = NMERR_TCP_WRITE; | |
377 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
378 |
8675 | 379 break; |
380 } | |
381 } | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
382 |
8675 | 383 /* Write the field type */ |
384 if (rc == NM_OK) { | |
385 bytes_to_send = g_snprintf(buffer, sizeof(buffer), | |
386 "&type=%u", field->type); | |
387 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
388 if (ret < 0) { | |
389 rc = NMERR_TCP_WRITE; | |
390 } | |
391 } | |
392 | |
393 /* If the field is a sub array then post its fields */ | |
394 if (rc == NM_OK && val > 0) { | |
395 if (field->type == NMFIELD_TYPE_ARRAY || | |
396 field->type == NMFIELD_TYPE_MV) { | |
397 | |
8933 | 398 rc = nm_write_fields(conn, (NMField *) field->ptr_value); |
8675 | 399 |
400 } | |
401 } | |
402 } | |
403 | |
404 return rc; | |
405 } | |
406 | |
407 NMERR_T | |
9360 | 408 nm_send_request(NMConn *conn, char *cmd, NMField *fields, |
409 nm_response_cb cb, gpointer data, NMRequest **request) | |
8675 | 410 { |
411 NMERR_T rc = NM_OK; | |
412 char buffer[512]; | |
413 int bytes_to_send; | |
414 int ret; | |
9360 | 415 NMField *request_fields = NULL; |
9268 | 416 char *str = NULL; |
8675 | 417 |
418 if (conn == NULL || cmd == NULL) | |
419 return NMERR_BAD_PARM; | |
420 | |
421 /* Write the post */ | |
422 bytes_to_send = g_snprintf(buffer, sizeof(buffer), | |
423 "POST /%s HTTP/1.0\r\n", cmd); | |
424 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
425 if (ret < 0) { | |
426 rc = NMERR_TCP_WRITE; | |
427 } | |
428 | |
429 /* Write headers */ | |
430 if (rc == NM_OK) { | |
431 if (strcmp("login", cmd) == 0) { | |
432 bytes_to_send = g_snprintf(buffer, sizeof(buffer), | |
433 "Host: %s:%d\r\n\r\n", conn->addr, conn->port); | |
434 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
435 if (ret < 0) { | |
436 rc = NMERR_TCP_WRITE; | |
437 } | |
438 } else { | |
439 bytes_to_send = g_snprintf(buffer, sizeof(buffer), "\r\n"); | |
440 ret = nm_tcp_write(conn, buffer, bytes_to_send); | |
441 if (ret < 0) { | |
442 rc = NMERR_TCP_WRITE; | |
443 } | |
444 } | |
445 } | |
446 | |
447 /* Add the transaction id to the request fields */ | |
448 if (rc == NM_OK) { | |
9268 | 449 if (fields) |
9360 | 450 request_fields = nm_copy_field_array(fields); |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
451 |
9268 | 452 str = g_strdup_printf("%d", ++(conn->trans_id)); |
9360 | 453 request_fields = nm_field_add_pointer(request_fields, NM_A_SZ_TRANSACTION_ID, 0, |
454 NMFIELD_METHOD_VALID, 0, | |
455 str, NMFIELD_TYPE_UTF8); | |
8675 | 456 } |
457 | |
458 /* Send the request to the server */ | |
459 if (rc == NM_OK) { | |
9360 | 460 rc = nm_write_fields(conn, request_fields); |
8675 | 461 } |
462 | |
463 /* Write the CRLF to terminate the data */ | |
464 if (rc == NM_OK) { | |
465 ret = nm_tcp_write(conn, "\r\n", strlen("\r\n")); | |
466 if (ret < 0) { | |
467 rc = NMERR_TCP_WRITE; | |
468 } | |
469 } | |
470 | |
9360 | 471 /* Create a request struct, add it to our queue, and return it */ |
8675 | 472 if (rc == NM_OK) { |
9360 | 473 NMRequest *new_request = nm_create_request(cmd, conn->trans_id, |
474 time(0), cb, NULL, data); | |
475 nm_conn_add_request_item(conn, new_request); | |
476 | |
477 /* Set the out param if it was sent in, otherwise release the request */ | |
478 if (request) | |
479 *request = new_request; | |
480 else | |
481 nm_release_request(new_request); | |
8675 | 482 } |
483 | |
9360 | 484 if (request_fields != NULL) |
485 nm_free_fields(&request_fields); | |
8675 | 486 |
487 return rc; | |
488 } | |
489 | |
490 NMERR_T | |
491 nm_read_header(NMConn * conn) | |
492 { | |
493 NMERR_T rc = NM_OK; | |
494 char buffer[512]; | |
495 char *ptr = NULL; | |
496 int i; | |
497 char rtn_buf[8]; | |
498 int rtn_code = 0; | |
499 | |
500 if (conn == NULL) | |
501 return NMERR_BAD_PARM; | |
502 | |
503 *buffer = '\0'; | |
504 rc = read_line(conn, buffer, sizeof(buffer)); | |
505 if (rc == NM_OK) { | |
506 | |
507 /* Find the return code */ | |
508 ptr = strchr(buffer, ' '); | |
509 if (ptr != NULL) { | |
510 ptr++; | |
511 | |
512 i = 0; | |
513 while (isdigit(*ptr) && (i < 3)) { | |
514 rtn_buf[i] = *ptr; | |
515 i++; | |
516 ptr++; | |
517 } | |
518 rtn_buf[i] = '\0'; | |
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
519 |
8675 | 520 if (i > 0) |
521 rtn_code = atoi(rtn_buf); | |
522 } | |
523 } | |
524 | |
525 /* Finish reading header, in the future we might want to do more processing here */ | |
526 /* TODO: handle more general redirects in the future */ | |
527 while ((rc == NM_OK) && (strcmp(buffer, "\r\n") != 0)) { | |
528 rc = read_line(conn, buffer, sizeof(buffer)); | |
529 } | |
530 | |
8933 | 531 if (rc == NM_OK && rtn_code == 301) |
532 rc = NMERR_SERVER_REDIRECT; | |
8675 | 533 |
534 return rc; | |
535 } | |
536 | |
537 NMERR_T | |
538 nm_read_fields(NMConn * conn, int count, NMField ** fields) | |
539 { | |
540 NMERR_T rc = NM_OK; | |
541 guint8 type; | |
542 guint8 method; | |
543 guint32 val; | |
544 char tag[64]; | |
545 NMField *sub_fields = NULL; | |
546 char *str = NULL; | |
547 | |
548 if (conn == NULL || fields == NULL) | |
549 return NMERR_BAD_PARM; | |
550 | |
551 do { | |
8753 | 552 if (count > 0) { |
8675 | 553 count--; |
554 } | |
555 | |
556 /* Read the field type, method, and tag */ | |
8933 | 557 rc = nm_read_all(conn, (char *)&type, sizeof(type)); |
8675 | 558 if (rc != NM_OK || type == 0) |
559 break; | |
560 | |
8933 | 561 rc = nm_read_all(conn, (char *)&method, sizeof(method)); |
8675 | 562 if (rc != NM_OK) |
563 break; | |
564 | |
8874 | 565 rc = nm_read_uint32(conn, &val); |
8675 | 566 if (rc != NM_OK) |
567 break; | |
568 | |
569 if (val > sizeof(tag)) { | |
570 rc = NMERR_PROTOCOL; | |
571 break; | |
572 } | |
573 | |
574 rc = nm_read_all(conn, tag, val); | |
575 if (rc != NM_OK) | |
576 break; | |
577 | |
578 if (type == NMFIELD_TYPE_MV || type == NMFIELD_TYPE_ARRAY) { | |
579 | |
580 /* Read the subarray (first read the number of items in the array) */ | |
8874 | 581 rc = nm_read_uint32(conn, &val); |
8675 | 582 if (rc != NM_OK) |
583 break; | |
584 | |
585 if (val > 0) { | |
586 rc = nm_read_fields(conn, val, &sub_fields); | |
587 if (rc != NM_OK) | |
588 break; | |
589 } | |
590 | |
8933 | 591 *fields = nm_field_add_pointer(*fields, tag, 0, method, |
592 0, sub_fields, type); | |
8675 | 593 |
594 sub_fields = NULL; | |
595 | |
596 } else if (type == NMFIELD_TYPE_UTF8 || type == NMFIELD_TYPE_DN) { | |
597 | |
598 /* Read the string (first read the length) */ | |
8874 | 599 rc = nm_read_uint32(conn, &val); |
8675 | 600 if (rc != NM_OK) |
601 break; | |
602 | |
8753 | 603 if (val >= NMFIELD_MAX_STR_LENGTH) { |
604 rc = NMERR_PROTOCOL; | |
605 break; | |
606 } | |
607 | |
8675 | 608 if (val > 0) { |
609 str = g_new0(char, val + 1); | |
610 | |
611 rc = nm_read_all(conn, str, val); | |
612 if (rc != NM_OK) | |
613 break; | |
8753 | 614 |
8933 | 615 *fields = nm_field_add_pointer(*fields, tag, 0, method, |
616 0, str, type); | |
8753 | 617 str = NULL; |
8675 | 618 } |
619 | |
620 } else { | |
621 | |
622 /* Read the numerical value */ | |
8874 | 623 rc = nm_read_uint32(conn, &val); |
8675 | 624 if (rc != NM_OK) |
625 break; | |
626 | |
8933 | 627 *fields = nm_field_add_number(*fields, tag, 0, method, |
628 0, val, type); | |
8675 | 629 } |
630 | |
631 } while ((type != 0) && (count != 0)); | |
632 | |
633 | |
634 if (str != NULL) { | |
635 g_free(str); | |
636 } | |
637 | |
638 if (sub_fields != NULL) { | |
639 nm_free_fields(&sub_fields); | |
640 } | |
641 | |
642 return rc; | |
643 } | |
644 | |
645 void | |
646 nm_conn_add_request_item(NMConn * conn, NMRequest * request) | |
647 { | |
648 if (conn == NULL || request == NULL) | |
649 return; | |
650 | |
651 nm_request_add_ref(request); | |
652 conn->requests = g_slist_append(conn->requests, request); | |
653 } | |
654 | |
655 void | |
656 nm_conn_remove_request_item(NMConn * conn, NMRequest * request) | |
657 { | |
658 if (conn == NULL || request == NULL) | |
659 return; | |
660 | |
661 conn->requests = g_slist_remove(conn->requests, request); | |
662 nm_release_request(request); | |
663 } | |
664 | |
665 NMRequest * | |
666 nm_conn_find_request(NMConn * conn, int trans_id) | |
667 { | |
668 NMRequest *req = NULL; | |
669 GSList *itr = NULL; | |
670 | |
671 if (conn == NULL) | |
672 return NULL; | |
673 | |
674 itr = conn->requests; | |
675 while (itr) { | |
676 req = (NMRequest *) itr->data; | |
677 if (req != NULL && nm_request_get_trans_id(req) == trans_id) { | |
678 return req; | |
679 } | |
680 itr = g_slist_next(itr); | |
681 } | |
682 return NULL; | |
683 } | |
684 | |
685 const char * | |
686 nm_conn_get_addr(NMConn * conn) | |
687 { | |
688 if (conn == NULL) | |
689 return NULL; | |
690 else | |
691 return conn->addr; | |
692 } | |
693 | |
694 int | |
695 nm_conn_get_port(NMConn * conn) | |
696 { | |
697 if (conn == NULL) | |
698 return -1; | |
699 else | |
700 return conn->port; | |
701 } |