Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

add miniupnp lib, add getopt helper class, create jabber client and p…

…ortfwd wrappers
  • Loading branch information...
commit bd79b308bf921fa58df943e2650a46b9a23708a9 1 parent d0df209
Richard Jones authored

Showing 39 changed files with 5,177 additions and 52 deletions. Show diff stats Hide diff stats

  1. +7 3 README.txt
  2. +1 1  conjist.pro
  3. +531 0 miniupnp/bsdqueue.h
  4. +24 0 miniupnp/codelength.h
  5. +15 0 miniupnp/declspec.h
  6. +113 0 miniupnp/igd_desc_parse.c
  7. +47 0 miniupnp/igd_desc_parse.h
  8. +113 0 miniupnp/minisoap.c
  9. +15 0 miniupnp/minisoap.h
  10. +109 0 miniupnp/minissdpc.c
  11. +15 0 miniupnp/minissdpc.h
  12. +33 0 miniupnp/miniupnp.pro
  13. +748 0 miniupnp/miniupnpc.c
  14. +110 0 miniupnp/miniupnpc.h
  15. +15 0 miniupnp/miniupnpcstrings.h
  16. +222 0 miniupnp/miniwget.c
  17. +28 0 miniupnp/miniwget.h
  18. +191 0 miniupnp/minixml.c
  19. +37 0 miniupnp/minixml.h
  20. +149 0 miniupnp/minixmlvalid.c
  21. +374 0 miniupnp/upnpc.c
  22. +573 0 miniupnp/upnpcommands.c
  23. +193 0 miniupnp/upnpcommands.h
  24. +66 0 miniupnp/upnperrors.c
  25. +26 0 miniupnp/upnperrors.h
  26. +127 0 miniupnp/upnpreplyparse.c
  27. +62 0 miniupnp/upnpreplyparse.h
  28. +101 0 src/conjist.cpp
  29. +40 0 src/conjist.h
  30. +628 0 src/getopt_helper.cpp
  31. +127 0 src/getopt_helper.h
  32. +66 0 src/jabberclient.cpp
  33. +34 0 src/jabberclient.h
  34. +9 3 src/main.cpp
  35. +130 0 src/portfwd.cpp
  36. +36 0 src/portfwd.h
  37. +9 3 src/servent.cpp
  38. +6 2 src/servent.h
  39. +47 40 src/src.pro
10 README.txt
@@ -17,9 +17,13 @@ doesn't act as a server.
17 17
18 18 Making it work
19 19 --------------
20   -1) qmake && make
21   -2) ./conjist <your jabber id> <your jabber password>
22   -3) profit! (check iTunes/Amarok/etc for new shares)
  20 +Get deps (see below) and build thusly: qmake && make
  21 +
  22 +To run, you must supply jabber details.
  23 +For example, if you were larry@gmail.com using gtalk and a lame password:
  24 +
  25 + conjist.exe --user larry --domain gmail.com --pass 123 \
  26 + --server talk.google.com --port 5222
23 27
24 28 Deps
25 29 ----
2  conjist.pro
@@ -2,4 +2,4 @@ TEMPLATE = subdirs
2 2 OBJECTS_DIR = build
3 3 MOC_DIR = build
4 4
5   -SUBDIRS = qxmpp src
  5 +SUBDIRS = qxmpp miniupnp src
531 miniupnp/bsdqueue.h
... ... @@ -0,0 +1,531 @@
  1 +/* $OpenBSD: queue.h,v 1.31 2005/11/25 08:06:25 otto Exp $ */
  2 +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
  3 +
  4 +/*
  5 + * Copyright (c) 1991, 1993
  6 + * The Regents of the University of California. All rights reserved.
  7 + *
  8 + * Redistribution and use in source and binary forms, with or without
  9 + * modification, are permitted provided that the following conditions
  10 + * are met:
  11 + * 1. Redistributions of source code must retain the above copyright
  12 + * notice, this list of conditions and the following disclaimer.
  13 + * 2. Redistributions in binary form must reproduce the above copyright
  14 + * notice, this list of conditions and the following disclaimer in the
  15 + * documentation and/or other materials provided with the distribution.
  16 + * 3. Neither the name of the University nor the names of its contributors
  17 + * may be used to endorse or promote products derived from this software
  18 + * without specific prior written permission.
  19 + *
  20 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30 + * SUCH DAMAGE.
  31 + *
  32 + * @(#)queue.h 8.5 (Berkeley) 8/20/94
  33 + */
  34 +
  35 +#ifndef _SYS_QUEUE_H_
  36 +#define _SYS_QUEUE_H_
  37 +
  38 +/*
  39 + * This file defines five types of data structures: singly-linked lists,
  40 + * lists, simple queues, tail queues, and circular queues.
  41 + *
  42 + *
  43 + * A singly-linked list is headed by a single forward pointer. The elements
  44 + * are singly linked for minimum space and pointer manipulation overhead at
  45 + * the expense of O(n) removal for arbitrary elements. New elements can be
  46 + * added to the list after an existing element or at the head of the list.
  47 + * Elements being removed from the head of the list should use the explicit
  48 + * macro for this purpose for optimum efficiency. A singly-linked list may
  49 + * only be traversed in the forward direction. Singly-linked lists are ideal
  50 + * for applications with large datasets and few or no removals or for
  51 + * implementing a LIFO queue.
  52 + *
  53 + * A list is headed by a single forward pointer (or an array of forward
  54 + * pointers for a hash table header). The elements are doubly linked
  55 + * so that an arbitrary element can be removed without a need to
  56 + * traverse the list. New elements can be added to the list before
  57 + * or after an existing element or at the head of the list. A list
  58 + * may only be traversed in the forward direction.
  59 + *
  60 + * A simple queue is headed by a pair of pointers, one the head of the
  61 + * list and the other to the tail of the list. The elements are singly
  62 + * linked to save space, so elements can only be removed from the
  63 + * head of the list. New elements can be added to the list before or after
  64 + * an existing element, at the head of the list, or at the end of the
  65 + * list. A simple queue may only be traversed in the forward direction.
  66 + *
  67 + * A tail queue is headed by a pair of pointers, one to the head of the
  68 + * list and the other to the tail of the list. The elements are doubly
  69 + * linked so that an arbitrary element can be removed without a need to
  70 + * traverse the list. New elements can be added to the list before or
  71 + * after an existing element, at the head of the list, or at the end of
  72 + * the list. A tail queue may be traversed in either direction.
  73 + *
  74 + * A circle queue is headed by a pair of pointers, one to the head of the
  75 + * list and the other to the tail of the list. The elements are doubly
  76 + * linked so that an arbitrary element can be removed without a need to
  77 + * traverse the list. New elements can be added to the list before or after
  78 + * an existing element, at the head of the list, or at the end of the list.
  79 + * A circle queue may be traversed in either direction, but has a more
  80 + * complex end of list detection.
  81 + *
  82 + * For details on the use of these macros, see the queue(3) manual page.
  83 + */
  84 +
  85 +#ifdef QUEUE_MACRO_DEBUG
  86 +#define _Q_INVALIDATE(a) (a) = ((void *)-1)
  87 +#else
  88 +#define _Q_INVALIDATE(a)
  89 +#endif
  90 +
  91 +/*
  92 + * Singly-linked List definitions.
  93 + */
  94 +#define SLIST_HEAD(name, type) \
  95 +struct name { \
  96 + struct type *slh_first; /* first element */ \
  97 +}
  98 +
  99 +#define SLIST_HEAD_INITIALIZER(head) \
  100 + { NULL }
  101 +
  102 +#ifdef SLIST_ENTRY
  103 +#undef SLIST_ENTRY
  104 +#endif
  105 +
  106 +#define SLIST_ENTRY(type) \
  107 +struct { \
  108 + struct type *sle_next; /* next element */ \
  109 +}
  110 +
  111 +/*
  112 + * Singly-linked List access methods.
  113 + */
  114 +#define SLIST_FIRST(head) ((head)->slh_first)
  115 +#define SLIST_END(head) NULL
  116 +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
  117 +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
  118 +
  119 +#define SLIST_FOREACH(var, head, field) \
  120 + for((var) = SLIST_FIRST(head); \
  121 + (var) != SLIST_END(head); \
  122 + (var) = SLIST_NEXT(var, field))
  123 +
  124 +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
  125 + for ((varp) = &SLIST_FIRST((head)); \
  126 + ((var) = *(varp)) != SLIST_END(head); \
  127 + (varp) = &SLIST_NEXT((var), field))
  128 +
  129 +/*
  130 + * Singly-linked List functions.
  131 + */
  132 +#define SLIST_INIT(head) { \
  133 + SLIST_FIRST(head) = SLIST_END(head); \
  134 +}
  135 +
  136 +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
  137 + (elm)->field.sle_next = (slistelm)->field.sle_next; \
  138 + (slistelm)->field.sle_next = (elm); \
  139 +} while (0)
  140 +
  141 +#define SLIST_INSERT_HEAD(head, elm, field) do { \
  142 + (elm)->field.sle_next = (head)->slh_first; \
  143 + (head)->slh_first = (elm); \
  144 +} while (0)
  145 +
  146 +#define SLIST_REMOVE_NEXT(head, elm, field) do { \
  147 + (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
  148 +} while (0)
  149 +
  150 +#define SLIST_REMOVE_HEAD(head, field) do { \
  151 + (head)->slh_first = (head)->slh_first->field.sle_next; \
  152 +} while (0)
  153 +
  154 +#define SLIST_REMOVE(head, elm, type, field) do { \
  155 + if ((head)->slh_first == (elm)) { \
  156 + SLIST_REMOVE_HEAD((head), field); \
  157 + } else { \
  158 + struct type *curelm = (head)->slh_first; \
  159 + \
  160 + while (curelm->field.sle_next != (elm)) \
  161 + curelm = curelm->field.sle_next; \
  162 + curelm->field.sle_next = \
  163 + curelm->field.sle_next->field.sle_next; \
  164 + _Q_INVALIDATE((elm)->field.sle_next); \
  165 + } \
  166 +} while (0)
  167 +
  168 +/*
  169 + * List definitions.
  170 + */
  171 +#define LIST_HEAD(name, type) \
  172 +struct name { \
  173 + struct type *lh_first; /* first element */ \
  174 +}
  175 +
  176 +#define LIST_HEAD_INITIALIZER(head) \
  177 + { NULL }
  178 +
  179 +#define LIST_ENTRY(type) \
  180 +struct { \
  181 + struct type *le_next; /* next element */ \
  182 + struct type **le_prev; /* address of previous next element */ \
  183 +}
  184 +
  185 +/*
  186 + * List access methods
  187 + */
  188 +#define LIST_FIRST(head) ((head)->lh_first)
  189 +#define LIST_END(head) NULL
  190 +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
  191 +#define LIST_NEXT(elm, field) ((elm)->field.le_next)
  192 +
  193 +#define LIST_FOREACH(var, head, field) \
  194 + for((var) = LIST_FIRST(head); \
  195 + (var)!= LIST_END(head); \
  196 + (var) = LIST_NEXT(var, field))
  197 +
  198 +/*
  199 + * List functions.
  200 + */
  201 +#define LIST_INIT(head) do { \
  202 + LIST_FIRST(head) = LIST_END(head); \
  203 +} while (0)
  204 +
  205 +#define LIST_INSERT_AFTER(listelm, elm, field) do { \
  206 + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
  207 + (listelm)->field.le_next->field.le_prev = \
  208 + &(elm)->field.le_next; \
  209 + (listelm)->field.le_next = (elm); \
  210 + (elm)->field.le_prev = &(listelm)->field.le_next; \
  211 +} while (0)
  212 +
  213 +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
  214 + (elm)->field.le_prev = (listelm)->field.le_prev; \
  215 + (elm)->field.le_next = (listelm); \
  216 + *(listelm)->field.le_prev = (elm); \
  217 + (listelm)->field.le_prev = &(elm)->field.le_next; \
  218 +} while (0)
  219 +
  220 +#define LIST_INSERT_HEAD(head, elm, field) do { \
  221 + if (((elm)->field.le_next = (head)->lh_first) != NULL) \
  222 + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
  223 + (head)->lh_first = (elm); \
  224 + (elm)->field.le_prev = &(head)->lh_first; \
  225 +} while (0)
  226 +
  227 +#define LIST_REMOVE(elm, field) do { \
  228 + if ((elm)->field.le_next != NULL) \
  229 + (elm)->field.le_next->field.le_prev = \
  230 + (elm)->field.le_prev; \
  231 + *(elm)->field.le_prev = (elm)->field.le_next; \
  232 + _Q_INVALIDATE((elm)->field.le_prev); \
  233 + _Q_INVALIDATE((elm)->field.le_next); \
  234 +} while (0)
  235 +
  236 +#define LIST_REPLACE(elm, elm2, field) do { \
  237 + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
  238 + (elm2)->field.le_next->field.le_prev = \
  239 + &(elm2)->field.le_next; \
  240 + (elm2)->field.le_prev = (elm)->field.le_prev; \
  241 + *(elm2)->field.le_prev = (elm2); \
  242 + _Q_INVALIDATE((elm)->field.le_prev); \
  243 + _Q_INVALIDATE((elm)->field.le_next); \
  244 +} while (0)
  245 +
  246 +/*
  247 + * Simple queue definitions.
  248 + */
  249 +#define SIMPLEQ_HEAD(name, type) \
  250 +struct name { \
  251 + struct type *sqh_first; /* first element */ \
  252 + struct type **sqh_last; /* addr of last next element */ \
  253 +}
  254 +
  255 +#define SIMPLEQ_HEAD_INITIALIZER(head) \
  256 + { NULL, &(head).sqh_first }
  257 +
  258 +#define SIMPLEQ_ENTRY(type) \
  259 +struct { \
  260 + struct type *sqe_next; /* next element */ \
  261 +}
  262 +
  263 +/*
  264 + * Simple queue access methods.
  265 + */
  266 +#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
  267 +#define SIMPLEQ_END(head) NULL
  268 +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
  269 +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
  270 +
  271 +#define SIMPLEQ_FOREACH(var, head, field) \
  272 + for((var) = SIMPLEQ_FIRST(head); \
  273 + (var) != SIMPLEQ_END(head); \
  274 + (var) = SIMPLEQ_NEXT(var, field))
  275 +
  276 +/*
  277 + * Simple queue functions.
  278 + */
  279 +#define SIMPLEQ_INIT(head) do { \
  280 + (head)->sqh_first = NULL; \
  281 + (head)->sqh_last = &(head)->sqh_first; \
  282 +} while (0)
  283 +
  284 +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
  285 + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
  286 + (head)->sqh_last = &(elm)->field.sqe_next; \
  287 + (head)->sqh_first = (elm); \
  288 +} while (0)
  289 +
  290 +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
  291 + (elm)->field.sqe_next = NULL; \
  292 + *(head)->sqh_last = (elm); \
  293 + (head)->sqh_last = &(elm)->field.sqe_next; \
  294 +} while (0)
  295 +
  296 +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
  297 + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
  298 + (head)->sqh_last = &(elm)->field.sqe_next; \
  299 + (listelm)->field.sqe_next = (elm); \
  300 +} while (0)
  301 +
  302 +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
  303 + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
  304 + (head)->sqh_last = &(head)->sqh_first; \
  305 +} while (0)
  306 +
  307 +/*
  308 + * Tail queue definitions.
  309 + */
  310 +#define TAILQ_HEAD(name, type) \
  311 +struct name { \
  312 + struct type *tqh_first; /* first element */ \
  313 + struct type **tqh_last; /* addr of last next element */ \
  314 +}
  315 +
  316 +#define TAILQ_HEAD_INITIALIZER(head) \
  317 + { NULL, &(head).tqh_first }
  318 +
  319 +#define TAILQ_ENTRY(type) \
  320 +struct { \
  321 + struct type *tqe_next; /* next element */ \
  322 + struct type **tqe_prev; /* address of previous next element */ \
  323 +}
  324 +
  325 +/*
  326 + * tail queue access methods
  327 + */
  328 +#define TAILQ_FIRST(head) ((head)->tqh_first)
  329 +#define TAILQ_END(head) NULL
  330 +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
  331 +#define TAILQ_LAST(head, headname) \
  332 + (*(((struct headname *)((head)->tqh_last))->tqh_last))
  333 +/* XXX */
  334 +#define TAILQ_PREV(elm, headname, field) \
  335 + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
  336 +#define TAILQ_EMPTY(head) \
  337 + (TAILQ_FIRST(head) == TAILQ_END(head))
  338 +
  339 +#define TAILQ_FOREACH(var, head, field) \
  340 + for((var) = TAILQ_FIRST(head); \
  341 + (var) != TAILQ_END(head); \
  342 + (var) = TAILQ_NEXT(var, field))
  343 +
  344 +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
  345 + for((var) = TAILQ_LAST(head, headname); \
  346 + (var) != TAILQ_END(head); \
  347 + (var) = TAILQ_PREV(var, headname, field))
  348 +
  349 +/*
  350 + * Tail queue functions.
  351 + */
  352 +#define TAILQ_INIT(head) do { \
  353 + (head)->tqh_first = NULL; \
  354 + (head)->tqh_last = &(head)->tqh_first; \
  355 +} while (0)
  356 +
  357 +#define TAILQ_INSERT_HEAD(head, elm, field) do { \
  358 + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
  359 + (head)->tqh_first->field.tqe_prev = \
  360 + &(elm)->field.tqe_next; \
  361 + else \
  362 + (head)->tqh_last = &(elm)->field.tqe_next; \
  363 + (head)->tqh_first = (elm); \
  364 + (elm)->field.tqe_prev = &(head)->tqh_first; \
  365 +} while (0)
  366 +
  367 +#define TAILQ_INSERT_TAIL(head, elm, field) do { \
  368 + (elm)->field.tqe_next = NULL; \
  369 + (elm)->field.tqe_prev = (head)->tqh_last; \
  370 + *(head)->tqh_last = (elm); \
  371 + (head)->tqh_last = &(elm)->field.tqe_next; \
  372 +} while (0)
  373 +
  374 +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
  375 + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
  376 + (elm)->field.tqe_next->field.tqe_prev = \
  377 + &(elm)->field.tqe_next; \
  378 + else \
  379 + (head)->tqh_last = &(elm)->field.tqe_next; \
  380 + (listelm)->field.tqe_next = (elm); \
  381 + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
  382 +} while (0)
  383 +
  384 +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
  385 + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
  386 + (elm)->field.tqe_next = (listelm); \
  387 + *(listelm)->field.tqe_prev = (elm); \
  388 + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
  389 +} while (0)
  390 +
  391 +#define TAILQ_REMOVE(head, elm, field) do { \
  392 + if (((elm)->field.tqe_next) != NULL) \
  393 + (elm)->field.tqe_next->field.tqe_prev = \
  394 + (elm)->field.tqe_prev; \
  395 + else \
  396 + (head)->tqh_last = (elm)->field.tqe_prev; \
  397 + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
  398 + _Q_INVALIDATE((elm)->field.tqe_prev); \
  399 + _Q_INVALIDATE((elm)->field.tqe_next); \
  400 +} while (0)
  401 +
  402 +#define TAILQ_REPLACE(head, elm, elm2, field) do { \
  403 + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
  404 + (elm2)->field.tqe_next->field.tqe_prev = \
  405 + &(elm2)->field.tqe_next; \
  406 + else \
  407 + (head)->tqh_last = &(elm2)->field.tqe_next; \
  408 + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
  409 + *(elm2)->field.tqe_prev = (elm2); \
  410 + _Q_INVALIDATE((elm)->field.tqe_prev); \
  411 + _Q_INVALIDATE((elm)->field.tqe_next); \
  412 +} while (0)
  413 +
  414 +/*
  415 + * Circular queue definitions.
  416 + */
  417 +#define CIRCLEQ_HEAD(name, type) \
  418 +struct name { \
  419 + struct type *cqh_first; /* first element */ \
  420 + struct type *cqh_last; /* last element */ \
  421 +}
  422 +
  423 +#define CIRCLEQ_HEAD_INITIALIZER(head) \
  424 + { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
  425 +
  426 +#define CIRCLEQ_ENTRY(type) \
  427 +struct { \
  428 + struct type *cqe_next; /* next element */ \
  429 + struct type *cqe_prev; /* previous element */ \
  430 +}
  431 +
  432 +/*
  433 + * Circular queue access methods
  434 + */
  435 +#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
  436 +#define CIRCLEQ_LAST(head) ((head)->cqh_last)
  437 +#define CIRCLEQ_END(head) ((void *)(head))
  438 +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
  439 +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
  440 +#define CIRCLEQ_EMPTY(head) \
  441 + (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
  442 +
  443 +#define CIRCLEQ_FOREACH(var, head, field) \
  444 + for((var) = CIRCLEQ_FIRST(head); \
  445 + (var) != CIRCLEQ_END(head); \
  446 + (var) = CIRCLEQ_NEXT(var, field))
  447 +
  448 +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
  449 + for((var) = CIRCLEQ_LAST(head); \
  450 + (var) != CIRCLEQ_END(head); \
  451 + (var) = CIRCLEQ_PREV(var, field))
  452 +
  453 +/*
  454 + * Circular queue functions.
  455 + */
  456 +#define CIRCLEQ_INIT(head) do { \
  457 + (head)->cqh_first = CIRCLEQ_END(head); \
  458 + (head)->cqh_last = CIRCLEQ_END(head); \
  459 +} while (0)
  460 +
  461 +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
  462 + (elm)->field.cqe_next = (listelm)->field.cqe_next; \
  463 + (elm)->field.cqe_prev = (listelm); \
  464 + if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
  465 + (head)->cqh_last = (elm); \
  466 + else \
  467 + (listelm)->field.cqe_next->field.cqe_prev = (elm); \
  468 + (listelm)->field.cqe_next = (elm); \
  469 +} while (0)
  470 +
  471 +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
  472 + (elm)->field.cqe_next = (listelm); \
  473 + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
  474 + if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
  475 + (head)->cqh_first = (elm); \
  476 + else \
  477 + (listelm)->field.cqe_prev->field.cqe_next = (elm); \
  478 + (listelm)->field.cqe_prev = (elm); \
  479 +} while (0)
  480 +
  481 +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
  482 + (elm)->field.cqe_next = (head)->cqh_first; \
  483 + (elm)->field.cqe_prev = CIRCLEQ_END(head); \
  484 + if ((head)->cqh_last == CIRCLEQ_END(head)) \
  485 + (head)->cqh_last = (elm); \
  486 + else \
  487 + (head)->cqh_first->field.cqe_prev = (elm); \
  488 + (head)->cqh_first = (elm); \
  489 +} while (0)
  490 +
  491 +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
  492 + (elm)->field.cqe_next = CIRCLEQ_END(head); \
  493 + (elm)->field.cqe_prev = (head)->cqh_last; \
  494 + if ((head)->cqh_first == CIRCLEQ_END(head)) \
  495 + (head)->cqh_first = (elm); \
  496 + else \
  497 + (head)->cqh_last->field.cqe_next = (elm); \
  498 + (head)->cqh_last = (elm); \
  499 +} while (0)
  500 +
  501 +#define CIRCLEQ_REMOVE(head, elm, field) do { \
  502 + if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
  503 + (head)->cqh_last = (elm)->field.cqe_prev; \
  504 + else \
  505 + (elm)->field.cqe_next->field.cqe_prev = \
  506 + (elm)->field.cqe_prev; \
  507 + if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
  508 + (head)->cqh_first = (elm)->field.cqe_next; \
  509 + else \
  510 + (elm)->field.cqe_prev->field.cqe_next = \
  511 + (elm)->field.cqe_next; \
  512 + _Q_INVALIDATE((elm)->field.cqe_prev); \
  513 + _Q_INVALIDATE((elm)->field.cqe_next); \
  514 +} while (0)
  515 +
  516 +#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
  517 + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
  518 + CIRCLEQ_END(head)) \
  519 + (head).cqh_last = (elm2); \
  520 + else \
  521 + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
  522 + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
  523 + CIRCLEQ_END(head)) \
  524 + (head).cqh_first = (elm2); \
  525 + else \
  526 + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
  527 + _Q_INVALIDATE((elm)->field.cqe_prev); \
  528 + _Q_INVALIDATE((elm)->field.cqe_next); \
  529 +} while (0)
  530 +
  531 +#endif /* !_SYS_QUEUE_H_ */
24 miniupnp/codelength.h
... ... @@ -0,0 +1,24 @@
  1 +/* $Id: codelength.h,v 1.1 2008/10/06 22:04:06 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * Author : Thomas BERNARD
  4 + * copyright (c) 2005-2008 Thomas Bernard
  5 + * This software is subjet to the conditions detailed in the
  6 + * provided LICENCE file. */
  7 +#ifndef __CODELENGTH_H__
  8 +#define __CODELENGTH_H__
  9 +
  10 +/* Encode length by using 7bit per Byte :
  11 + * Most significant bit of each byte specifies that the
  12 + * following byte is part of the code */
  13 +#define DECODELENGTH(n, p) n = 0; \
  14 + do { n = (n << 7) | (*p & 0x7f); } \
  15 + while(*(p++)&0x80);
  16 +
  17 +#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
  18 + if(n>=2097152) *(p++) = (n >> 21) | 0x80; \
  19 + if(n>=16384) *(p++) = (n >> 14) | 0x80; \
  20 + if(n>=128) *(p++) = (n >> 7) | 0x80; \
  21 + *(p++) = n & 0x7f;
  22 +
  23 +#endif
  24 +
15 miniupnp/declspec.h
... ... @@ -0,0 +1,15 @@
  1 +#ifndef __DECLSPEC_H__
  2 +#define __DECLSPEC_H__
  3 +
  4 +#if defined(WIN32) && !defined(STATICLIB)
  5 + #ifdef MINIUPNP_EXPORTS
  6 + #define LIBSPEC __declspec(dllexport)
  7 + #else
  8 + #define LIBSPEC __declspec(dllimport)
  9 + #endif
  10 +#else
  11 + #define LIBSPEC
  12 +#endif
  13 +
  14 +#endif
  15 +
113 miniupnp/igd_desc_parse.c
... ... @@ -0,0 +1,113 @@
  1 +/* $Id: igd_desc_parse.c,v 1.8 2008/04/23 11:51:06 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * http://miniupnp.free.fr/
  4 + * Author : Thomas Bernard
  5 + * Copyright (c) 2005-2008 Thomas Bernard
  6 + * This software is subject to the conditions detailed in the
  7 + * LICENCE file provided in this distribution.
  8 + * */
  9 +#include "igd_desc_parse.h"
  10 +#include <stdio.h>
  11 +#include <string.h>
  12 +
  13 +/* TODO : rewrite this code so it correctly handle descriptions with
  14 + * both WANIPConnection and/or WANPPPConnection */
  15 +
  16 +/* Start element handler :
  17 + * update nesting level counter and copy element name */
  18 +void IGDstartelt(void * d, const char * name, int l)
  19 +{
  20 + struct IGDdatas * datas = (struct IGDdatas *)d;
  21 + memcpy( datas->cureltname, name, l);
  22 + datas->cureltname[l] = '\0';
  23 + datas->level++;
  24 + if( (l==7) && !memcmp(name, "service", l) ) {
  25 + datas->controlurl_tmp[0] = '\0';
  26 + datas->eventsuburl_tmp[0] = '\0';
  27 + datas->scpdurl_tmp[0] = '\0';
  28 + datas->servicetype_tmp[0] = '\0';
  29 + }
  30 +}
  31 +
  32 +/* End element handler :
  33 + * update nesting level counter and update parser state if
  34 + * service element is parsed */
  35 +void IGDendelt(void * d, const char * name, int l)
  36 +{
  37 + struct IGDdatas * datas = (struct IGDdatas *)d;
  38 + datas->level--;
  39 + /*printf("endelt %2d %.*s\n", datas->level, l, name);*/
  40 + if( (l==7) && !memcmp(name, "service", l) )
  41 + {
  42 + /*
  43 + if( datas->state < 1
  44 + && !strcmp(datas->servicetype,
  45 + // "urn:schemas-upnp-org:service:WANIPConnection:1") )
  46 + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
  47 + datas->state ++;
  48 + */
  49 + if(0==strcmp(datas->servicetype_tmp,
  50 + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
  51 + memcpy(datas->controlurl_CIF, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE);
  52 + memcpy(datas->eventsuburl_CIF, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE);
  53 + memcpy(datas->scpdurl_CIF, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE);
  54 + memcpy(datas->servicetype_CIF, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE);
  55 + } else if(0==strcmp(datas->servicetype_tmp,
  56 + "urn:schemas-upnp-org:service:WANIPConnection:1")
  57 + || 0==strcmp(datas->servicetype_tmp,
  58 + "urn:schemas-upnp-org:service:WANPPPConnection:1") ) {
  59 + memcpy(datas->controlurl, datas->controlurl_tmp, MINIUPNPC_URL_MAXSIZE);
  60 + memcpy(datas->eventsuburl, datas->eventsuburl_tmp, MINIUPNPC_URL_MAXSIZE);
  61 + memcpy(datas->scpdurl, datas->scpdurl_tmp, MINIUPNPC_URL_MAXSIZE);
  62 + memcpy(datas->servicetype, datas->servicetype_tmp, MINIUPNPC_URL_MAXSIZE);
  63 + }
  64 + }
  65 +}
  66 +
  67 +/* Data handler :
  68 + * copy data depending on the current element name and state */
  69 +void IGDdata(void * d, const char * data, int l)
  70 +{
  71 + struct IGDdatas * datas = (struct IGDdatas *)d;
  72 + char * dstmember = 0;
  73 + /*printf("%2d %s : %.*s\n",
  74 + datas->level, datas->cureltname, l, data); */
  75 + if( !strcmp(datas->cureltname, "URLBase") )
  76 + dstmember = datas->urlbase;
  77 + else if( !strcmp(datas->cureltname, "serviceType") )
  78 + dstmember = datas->servicetype_tmp;
  79 + else if( !strcmp(datas->cureltname, "controlURL") )
  80 + dstmember = datas->controlurl_tmp;
  81 + else if( !strcmp(datas->cureltname, "eventSubURL") )
  82 + dstmember = datas->eventsuburl_tmp;
  83 + else if( !strcmp(datas->cureltname, "SCPDURL") )
  84 + dstmember = datas->scpdurl_tmp;
  85 +/* else if( !strcmp(datas->cureltname, "deviceType") )
  86 + dstmember = datas->devicetype_tmp;*/
  87 + if(dstmember)
  88 + {
  89 + if(l>=MINIUPNPC_URL_MAXSIZE)
  90 + l = MINIUPNPC_URL_MAXSIZE-1;
  91 + memcpy(dstmember, data, l);
  92 + dstmember[l] = '\0';
  93 + }
  94 +}
  95 +
  96 +void printIGD(struct IGDdatas * d)
  97 +{
  98 + printf("urlbase = %s\n", d->urlbase);
  99 + printf("WAN Device (Common interface config) :\n");
  100 + /*printf(" deviceType = %s\n", d->devicetype_CIF);*/
  101 + printf(" serviceType = %s\n", d->servicetype_CIF);
  102 + printf(" controlURL = %s\n", d->controlurl_CIF);
  103 + printf(" eventSubURL = %s\n", d->eventsuburl_CIF);
  104 + printf(" SCPDURL = %s\n", d->scpdurl_CIF);
  105 + printf("WAN Connection Device (IP or PPP Connection):\n");
  106 + /*printf(" deviceType = %s\n", d->devicetype);*/
  107 + printf(" servicetype = %s\n", d->servicetype);
  108 + printf(" controlURL = %s\n", d->controlurl);
  109 + printf(" eventSubURL = %s\n", d->eventsuburl);
  110 + printf(" SCPDURL = %s\n", d->scpdurl);
  111 +}
  112 +
  113 +
47 miniupnp/igd_desc_parse.h
... ... @@ -0,0 +1,47 @@
  1 +/* $Id: igd_desc_parse.h,v 1.6 2008/04/23 11:51:07 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * http://miniupnp.free.fr/
  4 + * Author : Thomas Bernard
  5 + * Copyright (c) 2005-2008 Thomas Bernard
  6 + * This software is subject to the conditions detailed in the
  7 + * LICENCE file provided in this distribution.
  8 + * */
  9 +#ifndef __IGD_DESC_PARSE_H__
  10 +#define __IGD_DESC_PARSE_H__
  11 +
  12 +/* Structure to store the result of the parsing of UPnP
  13 + * descriptions of Internet Gateway Devices */
  14 +#define MINIUPNPC_URL_MAXSIZE (128)
  15 +struct IGDdatas {
  16 + char cureltname[MINIUPNPC_URL_MAXSIZE];
  17 + char urlbase[MINIUPNPC_URL_MAXSIZE];
  18 + int level;
  19 + /*int state;*/
  20 + /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
  21 + char controlurl_CIF[MINIUPNPC_URL_MAXSIZE];
  22 + char eventsuburl_CIF[MINIUPNPC_URL_MAXSIZE];
  23 + char scpdurl_CIF[MINIUPNPC_URL_MAXSIZE];
  24 + char servicetype_CIF[MINIUPNPC_URL_MAXSIZE];
  25 + /*char devicetype_CIF[MINIUPNPC_URL_MAXSIZE];*/
  26 + /* "urn:schemas-upnp-org:service:WANIPConnection:1"
  27 + * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
  28 + char controlurl[MINIUPNPC_URL_MAXSIZE];
  29 + char eventsuburl[MINIUPNPC_URL_MAXSIZE];
  30 + char scpdurl[MINIUPNPC_URL_MAXSIZE];
  31 + char servicetype[MINIUPNPC_URL_MAXSIZE];
  32 + /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
  33 + /* tmp */
  34 + char controlurl_tmp[MINIUPNPC_URL_MAXSIZE];
  35 + char eventsuburl_tmp[MINIUPNPC_URL_MAXSIZE];
  36 + char scpdurl_tmp[MINIUPNPC_URL_MAXSIZE];
  37 + char servicetype_tmp[MINIUPNPC_URL_MAXSIZE];
  38 + /*char devicetype_tmp[MINIUPNPC_URL_MAXSIZE];*/
  39 +};
  40 +
  41 +void IGDstartelt(void *, const char *, int);
  42 +void IGDendelt(void *, const char *, int);
  43 +void IGDdata(void *, const char *, int);
  44 +void printIGD(struct IGDdatas *);
  45 +
  46 +#endif
  47 +
113 miniupnp/minisoap.c
... ... @@ -0,0 +1,113 @@
  1 +/* $Id: minisoap.c,v 1.16 2008/10/11 16:39:29 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * Author : Thomas Bernard
  4 + * Copyright (c) 2005 Thomas Bernard
  5 + * This software is subject to the conditions detailed in the
  6 + * LICENCE file provided in this distribution.
  7 + *
  8 + * Minimal SOAP implementation for UPnP protocol.
  9 + */
  10 +#include <stdio.h>
  11 +#include <string.h>
  12 +#ifdef WIN32
  13 +#include <io.h>
  14 +#include <winsock2.h>
  15 +#define snprintf _snprintf
  16 +#else
  17 +#include <unistd.h>
  18 +#include <sys/types.h>
  19 +#include <sys/socket.h>
  20 +#endif
  21 +#include "minisoap.h"
  22 +#include "miniupnpcstrings.h"
  23 +
  24 +/* only for malloc */
  25 +#include <stdlib.h>
  26 +
  27 +#ifdef WIN32
  28 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
  29 +#else
  30 +#define PRINT_SOCKET_ERROR(x) perror(x)
  31 +#endif
  32 +
  33 +/* httpWrite sends the headers and the body to the socket
  34 + * and returns the number of bytes sent */
  35 +static int
  36 +httpWrite(int fd, const char * body, int bodysize,
  37 + const char * headers, int headerssize)
  38 +{
  39 + int n = 0;
  40 + /*n = write(fd, headers, headerssize);*/
  41 + /*if(bodysize>0)
  42 + n += write(fd, body, bodysize);*/
  43 + /* Note : my old linksys router only took into account
  44 + * soap request that are sent into only one packet */
  45 + char * p;
  46 + /* TODO: AVOID MALLOC */
  47 + p = malloc(headerssize+bodysize);
  48 + if(!p)
  49 + return 0;
  50 + memcpy(p, headers, headerssize);
  51 + memcpy(p+headerssize, body, bodysize);
  52 + /*n = write(fd, p, headerssize+bodysize);*/
  53 + n = send(fd, p, headerssize+bodysize, 0);
  54 + if(n<0) {
  55 + PRINT_SOCKET_ERROR("send");
  56 + }
  57 + /* disable send on the socket */
  58 + /* draytek routers dont seems to like that... */
  59 +#if 0
  60 +#ifdef WIN32
  61 + if(shutdown(fd, SD_SEND)<0) {
  62 +#else
  63 + if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/
  64 +#endif
  65 + PRINT_SOCKET_ERROR("shutdown");
  66 + }
  67 +#endif
  68 + free(p);
  69 + return n;
  70 +}
  71 +
  72 +/* self explanatory */
  73 +int soapPostSubmit(int fd,
  74 + const char * url,
  75 + const char * host,
  76 + unsigned short port,
  77 + const char * action,
  78 + const char * body)
  79 +{
  80 + int bodysize;
  81 + char headerbuf[512];
  82 + int headerssize;
  83 + char portstr[8];
  84 + bodysize = (int)strlen(body);
  85 + /* We are not using keep-alive HTTP connections.
  86 + * HTTP/1.1 needs the header Connection: close to do that.
  87 + * This is the default with HTTP/1.0 */
  88 + /* Connection: Close is normally there only in HTTP/1.1 but who knows */
  89 + portstr[0] = '\0';
  90 + if(port != 80)
  91 + snprintf(portstr, sizeof(portstr), ":%hu", port);
  92 + headerssize = snprintf(headerbuf, sizeof(headerbuf),
  93 + "POST %s HTTP/1.1\r\n"
  94 +/* "POST %s HTTP/1.0\r\n"*/
  95 + "Host: %s%s\r\n"
  96 + "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
  97 + "Content-Length: %d\r\n"
  98 + "Content-Type: text/xml\r\n"
  99 + "SOAPAction: \"%s\"\r\n"
  100 + "Connection: Close\r\n"
  101 + "Cache-Control: no-cache\r\n" /* ??? */
  102 + "Pragma: no-cache\r\n"
  103 + "\r\n",
  104 + url, host, portstr, bodysize, action);
  105 +#ifdef DEBUG
  106 + printf("SOAP request : headersize=%d bodysize=%d\n",
  107 + headerssize, bodysize);
  108 + /*printf("%s", headerbuf);*/
  109 +#endif
  110 + return httpWrite(fd, body, bodysize, headerbuf, headerssize);
  111 +}
  112 +
  113 +
15 miniupnp/minisoap.h
... ... @@ -0,0 +1,15 @@
  1 +/* $Id: minisoap.h,v 1.3 2006/11/19 22:32:34 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * Author : Thomas Bernard
  4 + * Copyright (c) 2005 Thomas Bernard
  5 + * This software is subject to the conditions detailed in the
  6 + * LICENCE file provided in this distribution. */
  7 +#ifndef __MINISOAP_H__
  8 +#define __MINISOAP_H__
  9 +
  10 +/*int httpWrite(int, const char *, int, const char *);*/
  11 +int soapPostSubmit(int, const char *, const char *, unsigned short,
  12 + const char *, const char *);
  13 +
  14 +#endif
  15 +
109 miniupnp/minissdpc.c
... ... @@ -0,0 +1,109 @@
  1 +/* $Id: minissdpc.c,v 1.7 2008/12/18 17:45:48 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * Author : Thomas BERNARD
  4 + * copyright (c) 2005-2008 Thomas Bernard
  5 + * This software is subjet to the conditions detailed in the
  6 + * provided LICENCE file. */
  7 +/*#include <syslog.h>*/
  8 +#include <stdio.h>
  9 +#include <string.h>
  10 +#include <stdlib.h>
  11 +#include <unistd.h>
  12 +#include <sys/types.h>
  13 +#ifdef WIN32
  14 +#include <winsock2.h>
  15 +#include <Ws2tcpip.h>
  16 +#include <io.h>
  17 +#else
  18 +#include <sys/socket.h>
  19 +#include <sys/un.h>
  20 +#endif
  21 +
  22 +#include "minissdpc.h"
  23 +#include "miniupnpc.h"
  24 +
  25 +#include "codelength.h"
  26 +
  27 +struct UPNPDev *
  28 +getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
  29 +{
  30 + struct UPNPDev * tmp;
  31 + struct UPNPDev * devlist = NULL;
  32 + unsigned char buffer[2048];
  33 + ssize_t n;
  34 + unsigned char * p;
  35 + unsigned char * url;
  36 + unsigned int i;
  37 + unsigned int urlsize, stsize, usnsize, l;
  38 + int s;
  39 + struct sockaddr_un addr;
  40 +
  41 + s = socket(AF_UNIX, SOCK_STREAM, 0);
  42 + if(s < 0)
  43 + {
  44 + /*syslog(LOG_ERR, "socket(unix): %m");*/
  45 + perror("socket(unix)");
  46 + return NULL;
  47 + }
  48 + addr.sun_family = AF_UNIX;
  49 + strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
  50 + if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
  51 + {
  52 + /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
  53 + close(s);
  54 + return NULL;
  55 + }
  56 + stsize = strlen(devtype);
  57 + buffer[0] = 1; /* request type 1 : request devices/services by type */
  58 + p = buffer + 1;
  59 + l = stsize; CODELENGTH(l, p);
  60 + memcpy(p, devtype, stsize);
  61 + p += stsize;
  62 + if(write(s, buffer, p - buffer) < 0)
  63 + {
  64 + /*syslog(LOG_ERR, "write(): %m");*/
  65 + perror("minissdpc.c: write()");
  66 + close(s);
  67 + return NULL;
  68 + }
  69 + n = read(s, buffer, sizeof(buffer));
  70 + if(n<=0)
  71 + {
  72 + perror("minissdpc.c: read()");
  73 + close(s);
  74 + return NULL;
  75 + }
  76 + p = buffer + 1;
  77 + for(i = 0; i < buffer[0]; i++)
  78 + {
  79 + if(p+2>=buffer+sizeof(buffer))
  80 + break;
  81 + DECODELENGTH(urlsize, p);
  82 + if(p+urlsize+2>=buffer+sizeof(buffer))
  83 + break;
  84 + url = p;
  85 + p += urlsize;
  86 + DECODELENGTH(stsize, p);
  87 + if(p+stsize+2>=buffer+sizeof(buffer))
  88 + break;
  89 + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
  90 + tmp->pNext = devlist;
  91 + tmp->descURL = tmp->buffer;
  92 + tmp->st = tmp->buffer + 1 + urlsize;
  93 + memcpy(tmp->buffer, url, urlsize);
  94 + tmp->buffer[urlsize] = '\0';
  95 + memcpy(tmp->buffer + urlsize + 1, p, stsize);
  96 + p += stsize;
  97 + tmp->buffer[urlsize+1+stsize] = '\0';
  98 + devlist = tmp;
  99 + /* added for compatibility with recent versions of MiniSSDPd
  100 + * >= 2007/12/19 */
  101 + DECODELENGTH(usnsize, p);
  102 + p += usnsize;
  103 + if(p>buffer + sizeof(buffer))
  104 + break;
  105 + }
  106 + close(s);
  107 + return devlist;
  108 +}
  109 +
15 miniupnp/minissdpc.h
... ... @@ -0,0 +1,15 @@
  1 +/* $Id: minissdpc.h,v 1.1 2007/08/31 15:15:33 nanard Exp $ */
  2 +/* Project: miniupnp
  3 + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
  4 + * Author: Thomas Bernard
  5 + * Copyright (c) 2005-2007 Thomas Bernard
  6 + * This software is subjects to the conditions detailed
  7 + * in the LICENCE file provided within this distribution */
  8 +#ifndef __MINISSDPC_H__
  9 +#define __MINISSDPC_H__
  10 +
  11 +struct UPNPDev *
  12 +getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath);
  13 +
  14 +#endif
  15 +
33 miniupnp/miniupnp.pro
... ... @@ -0,0 +1,33 @@
  1 +TEMPLATE = lib
  2 +QT -= all
  3 +CONFIG += staticlib release
  4 +TARGET = miniupnp
  5 +OBJECTS_DIR = ../build
  6 +MOC_DIR = ../build
  7 +
  8 +SOURCES += igd_desc_parse.c \
  9 +minisoap.c \
  10 +minissdpc.c \
  11 +miniupnpc.c \
  12 +miniwget.c \
  13 +minixml.c \
  14 +minixmlvalid.c \
  15 +upnpc.c \
  16 +upnpcommands.c \
  17 +upnperrors.c \
  18 +upnpreplyparse.c
  19 +
  20 +HEADERS += bsdqueue.h \
  21 +codelength.h \
  22 +declspec.h \
  23 +igd_desc_parse.h \
  24 +minisoap.h \
  25 +minissdpc.h \
  26 +miniupnpc.h \
  27 +miniupnpcstrings.h \
  28 +miniwget.h \
  29 +minixml.h \
  30 +upnpcommands.h \
  31 +upnperrors.h \
  32 +upnpreplyparse.h
  33 +
748 miniupnp/miniupnpc.c
... ... @@ -0,0 +1,748 @@
  1 +/* $Id: miniupnpc.c,v 1.57 2008/12/18 17:46:36 nanard Exp $ */
  2 +/* Project : miniupnp
  3 + * Author : Thomas BERNARD
  4 + * copyright (c) 2005-2007 Thomas Bernard
  5 + * This software is subjet to the conditions detailed in the
  6 + * provided LICENCE file. */
  7 +#include <stdio.h>
  8 +#include <stdlib.h>
  9 +#include <string.h>
  10 +#ifdef WIN32
  11 +/* Win32 Specific includes and defines */
  12 +#include <winsock2.h>
  13 +#include <Ws2tcpip.h>
  14 +#include <io.h>
  15 +#define snprintf _snprintf
  16 +#if defined(_MSC_VER) && (_MSC_VER >= 1400)
  17 +#define strncasecmp _memicmp
  18 +#else
  19 +#define strncasecmp memicmp
  20 +#endif
  21 +#define MAXHOSTNAMELEN 64
  22 +#else
  23 +/* Standard POSIX includes */
  24 +#include <unistd.h>
  25 +#include <sys/socket.h>
  26 +#include <sys/types.h>
  27 +#include <sys/param.h>
  28 +#include <netinet/in.h>
  29 +#include <arpa/inet.h>
  30 +#include <poll.h>
  31 +#include <netdb.h>
  32 +#define closesocket close
  33 +#endif
  34 +#include "miniupnpc.h"
  35 +#include "minissdpc.h"
  36 +#include "miniwget.h"
  37 +#include "minisoap.h"
  38 +#include "minixml.h"
  39 +#include "upnpcommands.h"
  40 +
  41 +#ifdef WIN32
  42 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
  43 +#else
  44 +#define PRINT_SOCKET_ERROR(x) perror(x)
  45 +#endif
  46 +
  47 +#define SOAPPREFIX "s"
  48 +#define SERVICEPREFIX "u"
  49 +#define SERVICEPREFIX2 'u'
  50 +
  51 +/* root description parsing */
  52 +void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
  53 +{
  54 + struct xmlparser parser;
  55 + /* xmlparser object */
  56 + parser.xmlstart = buffer;
  57 + parser.xmlsize = bufsize;
  58 + parser.data = data;
  59 + parser.starteltfunc = IGDstartelt;
  60 + parser.endeltfunc = IGDendelt;
  61 + parser.datafunc = IGDdata;
  62 + parser.attfunc = 0;
  63 + parsexml(&parser);
  64 +#ifdef DEBUG
  65 + printIGD(data);
  66 +#endif
  67 +}
  68 +
  69 +/* Content-length: nnn */
  70 +static int getcontentlenfromline(const char * p, int n)
  71 +{
  72 + static const char contlenstr[] = "content-length";
  73 + const char * p2 = contlenstr;
  74 + int a = 0;
  75 + while(*p2)
  76 + {
  77 + if(n==0)
  78 + return -1;
  79 + if(*p2 != *p && *p2 != (*p + 32))
  80 + return -1;
  81 + p++; p2++; n--;
  82 + }
  83 + if(n==0)
  84 + return -1;
  85 + if(*p != ':')
  86 + return -1;
  87 + p++; n--;
  88 + while(*p == ' ')
  89 + {
  90 + if(n==0)
  91 + return -1;
  92 + p++; n--;
  93 + }
  94 + while(*p >= '0' && *p <= '9')
  95 + {
  96 + if(n==0)
  97 + return -1;
  98 + a = (a * 10) + (*p - '0');
  99 + p++; n--;
  100 + }
  101 + return a;
  102 +}
  103 +
  104 +static void
  105 +getContentLengthAndHeaderLength(char * p, int n,
  106 + int * contentlen, int * headerlen)
  107 +{
  108 + char * line;
  109 + int linelen;
  110 + int r;
  111 + line = p;
  112 + while(line < p + n)
  113 + {
  114 + linelen = 0;
  115 + while(line[linelen] != '\r' && line[linelen] != '\r')
  116 + {
  117 + if(line+linelen >= p+n)
  118 + return;
  119 + linelen++;
  120 + }
  121 + r = getcontentlenfromline(line, linelen);
  122 + if(r>0)
  123 + *contentlen = r;
  124 + line = line + linelen + 2;
  125 + if(line[0] == '\r' && line[1] == '\n')
  126 + {
  127 + *headerlen = (line - p) + 2;
  128 + return;
  129 + }
  130 + }
  131 +}
  132 +
  133 +/* simpleUPnPcommand :
  134 + * not so simple !
  135 + * return values :
  136 + * 0 - OK
  137 + * -1 - error */
  138 +int simpleUPnPcommand(int s, const char * url, const char * service,
  139 + const char * action, struct UPNParg * args,
  140 + char * buffer, int * bufsize)
  141 +{
  142 + if(!url) return -1;
  143 + struct sockaddr_in dest;
  144 + char hostname[MAXHOSTNAMELEN+1];
  145 + unsigned short port = 0;
  146 + char * path;
  147 + char soapact[128];
  148 + char soapbody[2048];
  149 + char * buf;